71#include "llvm/IR/IntrinsicsPowerPC.h"
106#define DEBUG_TYPE "ppc-lowering"
109 "disable-p10-store-forward",
133 cl::desc(
"disable vector permute decomposition"),
137 "disable-auto-paired-vec-st",
138 cl::desc(
"disable automatically generated 32byte paired vector stores"),
143 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
147 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
151 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
152 "function to use initial-exec"));
157 "Number of shuffles lowered to a VPERM or XXPERM");
158STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
181 initializeAddrModeMap();
184 bool isPPC64 = Subtarget.
isPPC64();
193 if (!Subtarget.hasEFPU2())
218 if (Subtarget.isISA3_0()) {
248 if (!Subtarget.hasSPE()) {
256 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
257 for (
MVT VT : ScalarIntVTs) {
264 if (Subtarget.useCRBits()) {
267 if (isPPC64 || Subtarget.hasFPCVT()) {
270 isPPC64 ? MVT::i64 : MVT::i32);
273 isPPC64 ? MVT::i64 : MVT::i32);
277 isPPC64 ? MVT::i64 : MVT::i32);
280 isPPC64 ? MVT::i64 : MVT::i32);
284 isPPC64 ? MVT::i64 : MVT::i32);
287 isPPC64 ? MVT::i64 : MVT::i32);
291 isPPC64 ? MVT::i64 : MVT::i32);
294 isPPC64 ? MVT::i64 : MVT::i32);
341 if (Subtarget.isISA3_0()) {
376 if (!Subtarget.hasSPE()) {
381 if (Subtarget.hasVSX()) {
386 if (Subtarget.hasFSQRT()) {
391 if (Subtarget.hasFPRND()) {
432 if (Subtarget.hasSPE()) {
442 if (Subtarget.hasSPE())
446 if (!Subtarget.hasFSQRT() &&
447 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
451 if (!Subtarget.hasFSQRT() &&
452 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
453 Subtarget.hasFRES()))
456 if (Subtarget.hasFCPSGN()) {
464 if (Subtarget.hasFPRND()) {
478 if (Subtarget.isISA3_1()) {
489 if (Subtarget.isISA3_0()) {
509 if (!Subtarget.useCRBits()) {
522 if (!Subtarget.useCRBits())
525 if (Subtarget.hasFPU()) {
536 if (!Subtarget.useCRBits())
541 if (Subtarget.hasSPE()) {
565 if (Subtarget.hasDirectMove() && isPPC64) {
570 if (TM.Options.UnsafeFPMath) {
673 if (Subtarget.hasSPE()) {
695 if (Subtarget.has64BitSupport()) {
710 if (Subtarget.hasLFIWAX() || Subtarget.
isPPC64()) {
716 if (Subtarget.hasSPE()) {
726 if (Subtarget.hasFPCVT()) {
727 if (Subtarget.has64BitSupport()) {
748 if (Subtarget.use64BitRegs()) {
766 if (Subtarget.has64BitSupport()) {
773 if (Subtarget.hasVSX()) {
780 if (Subtarget.hasAltivec()) {
781 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
796 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
809 if (Subtarget.hasVSX()) {
815 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
825 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
899 if (!Subtarget.hasP8Vector()) {
941 if (Subtarget.hasAltivec())
942 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
945 if (Subtarget.hasP8Altivec())
956 if (Subtarget.hasVSX()) {
962 if (Subtarget.hasP8Altivec())
967 if (Subtarget.isISA3_1()) {
1013 if (Subtarget.hasVSX()) {
1016 if (Subtarget.hasP8Vector()) {
1020 if (Subtarget.hasDirectMove() && isPPC64) {
1034 if (TM.Options.UnsafeFPMath) {
1071 if (Subtarget.hasP8Vector())
1080 if (Subtarget.hasP8Altivec()) {
1107 if (Subtarget.isISA3_1())
1210 if (Subtarget.hasP8Altivec()) {
1215 if (Subtarget.hasP9Vector()) {
1220 if (Subtarget.useCRBits()) {
1280 }
else if (Subtarget.hasVSX()) {
1305 for (
MVT VT : {MVT::f32, MVT::f64}) {
1324 if (Subtarget.hasP9Altivec()) {
1325 if (Subtarget.isISA3_1()) {
1348 if (Subtarget.hasP10Vector()) {
1353 if (Subtarget.pairedVectorMemops()) {
1358 if (Subtarget.hasMMA()) {
1359 if (Subtarget.isISAFuture())
1368 if (Subtarget.has64BitSupport())
1371 if (Subtarget.isISA3_1())
1389 if (Subtarget.hasAltivec()) {
1406 if (Subtarget.hasFPCVT())
1409 if (Subtarget.useCRBits())
1418 if (Subtarget.useCRBits()) {
1449 setLibcallName(RTLIB::MEMCPY, isPPC64 ?
"___memmove64" :
"___memmove");
1450 setLibcallName(RTLIB::MEMMOVE, isPPC64 ?
"___memmove64" :
"___memmove");
1451 setLibcallName(RTLIB::MEMSET, isPPC64 ?
"___memset64" :
"___memset");
1452 setLibcallName(RTLIB::BZERO, isPPC64 ?
"___bzero64" :
"___bzero");
1457 if (Subtarget.useCRBits()) {
1563void PPCTargetLowering::initializeAddrModeMap() {
1614 if (MaxAlign == MaxMaxAlign)
1617 if (MaxMaxAlign >= 32 &&
1618 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1619 MaxAlign =
Align(32);
1620 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1622 MaxAlign =
Align(16);
1626 if (EltAlign > MaxAlign)
1627 MaxAlign = EltAlign;
1629 for (
auto *EltTy : STy->elements()) {
1632 if (EltAlign > MaxAlign)
1633 MaxAlign = EltAlign;
1634 if (MaxAlign == MaxMaxAlign)
1647 if (Subtarget.hasAltivec())
1649 return Alignment.
value();
1657 return Subtarget.hasSPE();
1665 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &
Index)
const {
1666 if (!Subtarget.
isPPC64() || !Subtarget.hasVSX())
1670 if (VTy->getScalarType()->isIntegerTy()) {
1672 if (ElemSizeInBits == 32) {
1676 if (ElemSizeInBits == 64) {
1702 return "PPCISD::FTSQRT";
1704 return "PPCISD::FSQRT";
1709 return "PPCISD::XXSPLTI_SP_TO_DP";
1711 return "PPCISD::XXSPLTI32DX";
1715 return "PPCISD::XXPERM";
1735 return "PPCISD::CALL_RM";
1737 return "PPCISD::CALL_NOP_RM";
1739 return "PPCISD::CALL_NOTOC_RM";
1744 return "PPCISD::BCTRL_RM";
1746 return "PPCISD::BCTRL_LOAD_TOC_RM";
1758 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1760 return "PPCISD::ANDI_rec_1_EQ_BIT";
1762 return "PPCISD::ANDI_rec_1_GT_BIT";
1777 return "PPCISD::ST_VSR_SCAL_INT";
1806 return "PPCISD::PADDI_DTPREL";
1822 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1824 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1834 return "PPCISD::STRICT_FADDRTZ";
1836 return "PPCISD::STRICT_FCTIDZ";
1838 return "PPCISD::STRICT_FCTIWZ";
1840 return "PPCISD::STRICT_FCTIDUZ";
1842 return "PPCISD::STRICT_FCTIWUZ";
1844 return "PPCISD::STRICT_FCFID";
1846 return "PPCISD::STRICT_FCFIDU";
1848 return "PPCISD::STRICT_FCFIDS";
1850 return "PPCISD::STRICT_FCFIDUS";
1853 return "PPCISD::STORE_COND";
1861 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1878 return CFP->getValueAPF().isZero();
1883 return CFP->getValueAPF().isZero();
1891 return Op < 0 ||
Op == Val;
1903 if (ShuffleKind == 0) {
1906 for (
unsigned i = 0; i != 16; ++i)
1909 }
else if (ShuffleKind == 2) {
1912 for (
unsigned i = 0; i != 16; ++i)
1915 }
else if (ShuffleKind == 1) {
1916 unsigned j = IsLE ? 0 : 1;
1917 for (
unsigned i = 0; i != 8; ++i)
1934 if (ShuffleKind == 0) {
1937 for (
unsigned i = 0; i != 16; i += 2)
1941 }
else if (ShuffleKind == 2) {
1944 for (
unsigned i = 0; i != 16; i += 2)
1948 }
else if (ShuffleKind == 1) {
1949 unsigned j = IsLE ? 0 : 2;
1950 for (
unsigned i = 0; i != 8; i += 2)
1971 if (!Subtarget.hasP8Vector())
1975 if (ShuffleKind == 0) {
1978 for (
unsigned i = 0; i != 16; i += 4)
1984 }
else if (ShuffleKind == 2) {
1987 for (
unsigned i = 0; i != 16; i += 4)
1993 }
else if (ShuffleKind == 1) {
1994 unsigned j = IsLE ? 0 : 4;
1995 for (
unsigned i = 0; i != 8; i += 4)
2012 unsigned LHSStart,
unsigned RHSStart) {
2013 if (
N->getValueType(0) != MVT::v16i8)
2015 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
2016 "Unsupported merge size!");
2018 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2019 for (
unsigned j = 0; j != UnitSize; ++j) {
2021 LHSStart+j+i*UnitSize) ||
2023 RHSStart+j+i*UnitSize))
2038 if (ShuffleKind == 1)
2040 else if (ShuffleKind == 2)
2045 if (ShuffleKind == 1)
2047 else if (ShuffleKind == 0)
2063 if (ShuffleKind == 1)
2065 else if (ShuffleKind == 2)
2070 if (ShuffleKind == 1)
2072 else if (ShuffleKind == 0)
2122 unsigned RHSStartValue) {
2123 if (
N->getValueType(0) != MVT::v16i8)
2126 for (
unsigned i = 0; i < 2; ++i)
2127 for (
unsigned j = 0; j < 4; ++j)
2129 i*RHSStartValue+j+IndexOffset) ||
2131 i*RHSStartValue+j+IndexOffset+8))
2153 unsigned indexOffset = CheckEven ? 4 : 0;
2154 if (ShuffleKind == 1)
2156 else if (ShuffleKind == 2)
2162 unsigned indexOffset = CheckEven ? 0 : 4;
2163 if (ShuffleKind == 1)
2165 else if (ShuffleKind == 0)
2181 if (
N->getValueType(0) != MVT::v16i8)
2188 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2191 if (i == 16)
return -1;
2196 if (ShiftAmt < i)
return -1;
2201 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2203 for (++i; i != 16; ++i)
2206 }
else if (ShuffleKind == 1) {
2208 for (++i; i != 16; ++i)
2215 ShiftAmt = 16 - ShiftAmt;
2224 EVT VT =
N->getValueType(0);
2225 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2226 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2229 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2233 if (
N->getMaskElt(0) % EltSize != 0)
2238 unsigned ElementBase =
N->getMaskElt(0);
2241 if (ElementBase >= 16)
2246 for (
unsigned i = 1; i != EltSize; ++i)
2247 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2250 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2251 if (
N->getMaskElt(i) < 0)
continue;
2252 for (
unsigned j = 0; j != EltSize; ++j)
2253 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2270 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2271 "Unexpected element width.");
2272 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2274 unsigned NumOfElem = 16 / Width;
2275 unsigned MaskVal[16];
2276 for (
unsigned i = 0; i < NumOfElem; ++i) {
2277 MaskVal[0] =
N->getMaskElt(i * Width);
2278 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2280 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2284 for (
unsigned int j = 1; j < Width; ++j) {
2285 MaskVal[j] =
N->getMaskElt(i * Width + j);
2286 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2296 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2301 unsigned M0 =
N->getMaskElt(0) / 4;
2302 unsigned M1 =
N->getMaskElt(4) / 4;
2303 unsigned M2 =
N->getMaskElt(8) / 4;
2304 unsigned M3 =
N->getMaskElt(12) / 4;
2305 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2306 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2311 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2312 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2313 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2314 InsertAtByte = IsLE ? 12 : 0;
2319 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2320 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2321 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2322 InsertAtByte = IsLE ? 8 : 4;
2327 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2328 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2329 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2330 InsertAtByte = IsLE ? 4 : 8;
2335 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2336 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2337 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2338 InsertAtByte = IsLE ? 0 : 12;
2345 if (
N->getOperand(1).isUndef()) {
2348 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2349 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2350 InsertAtByte = IsLE ? 12 : 0;
2353 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2354 InsertAtByte = IsLE ? 8 : 4;
2357 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2358 InsertAtByte = IsLE ? 4 : 8;
2361 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2362 InsertAtByte = IsLE ? 0 : 12;
2371 bool &Swap,
bool IsLE) {
2372 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2378 unsigned M0 =
N->getMaskElt(0) / 4;
2379 unsigned M1 =
N->getMaskElt(4) / 4;
2380 unsigned M2 =
N->getMaskElt(8) / 4;
2381 unsigned M3 =
N->getMaskElt(12) / 4;
2385 if (
N->getOperand(1).isUndef()) {
2386 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2387 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2390 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2396 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2400 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2405 ShiftElts = (8 -
M0) % 8;
2406 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2411 ShiftElts = (4 -
M0) % 4;
2416 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2421 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2433 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2438 for (
int i = 0; i < 16; i += Width)
2439 if (
N->getMaskElt(i) != i + Width - 1)
2470 bool &Swap,
bool IsLE) {
2471 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2477 unsigned M0 =
N->getMaskElt(0) / 8;
2478 unsigned M1 =
N->getMaskElt(8) / 8;
2479 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2483 if (
N->getOperand(1).isUndef()) {
2484 if ((
M0 |
M1) < 2) {
2485 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2493 if (
M0 > 1 &&
M1 < 2) {
2503 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2508 }
else if (
M0 > 1 &&
M1 < 2) {
2516 DM = (
M0 << 1) + (
M1 & 1);
2531 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2536 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2553 if (EltSize < ByteSize) {
2554 unsigned Multiple = ByteSize/EltSize;
2556 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2559 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2560 if (
N->getOperand(i).isUndef())
continue;
2564 if (!UniquedVals[i&(Multiple-1)].
getNode())
2566 else if (UniquedVals[i&(Multiple-1)] !=
N->
getOperand(i))
2576 bool LeadingZero =
true;
2577 bool LeadingOnes =
true;
2578 for (
unsigned i = 0; i != Multiple-1; ++i) {
2579 if (!UniquedVals[i].
getNode())
continue;
2586 if (!UniquedVals[Multiple-1].
getNode())
2593 if (!UniquedVals[Multiple-1].
getNode())
2604 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2605 if (
N->getOperand(i).isUndef())
continue;
2614 unsigned ValSizeInBytes = EltSize;
2617 Value = CN->getZExtValue();
2619 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2626 if (ValSizeInBytes < ByteSize)
return SDValue();
2637 if (MaskVal == 0)
return SDValue();
2657 Imm = (int16_t)
N->getAsZExtVal();
2658 if (
N->getValueType(0) == MVT::i32)
2659 return Imm == (int32_t)
N->getAsZExtVal();
2661 return Imm == (int64_t)
N->getAsZExtVal();
2679 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2689 if (Memop->getMemoryVT() == MVT::f64) {
2690 Base =
N.getOperand(0);
2706 Imm = (int64_t)
N->getAsZExtVal();
2734 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2739 Base =
N.getOperand(0);
2742 }
else if (
N.getOpcode() ==
ISD::OR) {
2744 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2756 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2757 Base =
N.getOperand(0);
2828 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2834 Base =
N.getOperand(0);
2837 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2839 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2840 "Cannot handle constant offsets yet!");
2846 Base =
N.getOperand(0);
2849 }
else if (
N.getOpcode() ==
ISD::OR) {
2852 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2866 Base =
N.getOperand(0);
2879 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2882 CN->getValueType(0));
2887 if ((CN->getValueType(0) == MVT::i32 ||
2888 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2889 (!EncodingAlignment ||
2890 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2891 int Addr = (int)CN->getZExtValue();
2898 unsigned Opc = CN->
getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2919 if (
N.getValueType() != MVT::i64)
2981 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2982 Base =
N.getOperand(0);
3026 EVT MemVT = LD->getMemoryVT();
3033 if (!ST.hasP8Vector())
3038 if (!ST.hasP9Vector())
3051 if (UI.getUse().get().getResNo() == 0 &&
3073 Ptr = LD->getBasePtr();
3074 VT = LD->getMemoryVT();
3075 Alignment = LD->getAlign();
3077 Ptr = ST->getBasePtr();
3078 VT = ST->getMemoryVT();
3079 Alignment = ST->getAlign();
3118 if (VT != MVT::i64) {
3123 if (Alignment <
Align(4))
3133 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3150 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3192 const bool Is64Bit = Subtarget.
isPPC64();
3193 EVT VT = Is64Bit ? MVT::i64 : MVT::i32;
3207 EVT PtrVT =
Op.getValueType();
3223 return getTOCEntry(DAG,
SDLoc(CP), GA);
3226 unsigned MOHiFlag, MOLoFlag;
3233 return getTOCEntry(DAG,
SDLoc(CP), GA);
3293 EVT PtrVT =
Op.getValueType();
3311 return getTOCEntry(DAG,
SDLoc(JT), GA);
3314 unsigned MOHiFlag, MOLoFlag;
3321 return getTOCEntry(DAG,
SDLoc(GA), GA);
3331 EVT PtrVT =
Op.getValueType();
3350 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3359 unsigned MOHiFlag, MOLoFlag;
3370 return LowerGlobalTLSAddressAIX(
Op, DAG);
3372 return LowerGlobalTLSAddressLinux(
Op, DAG);
3394 if (
I.getOpcode() == Instruction::Call)
3396 if (
Function *CF = CI->getCalledFunction())
3397 if (CF->isDeclaration() &&
3398 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3406 unsigned TLSGVCnt = TLSGV.
size();
3416 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3431 bool Is64Bit = Subtarget.
isPPC64();
3435 if (Subtarget.hasAIXShLibTLSModelOpt())
3441 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3442 bool HasAIXSmallTLSGlobalAttr =
false;
3445 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3449 if (GVar->hasAttribute(
"aix-small-tls"))
3450 HasAIXSmallTLSGlobalAttr =
true;
3469 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3470 IsTLSLocalExecModel) {
3490 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3492 "currently only supported on AIX (64-bit mode).");
3498 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3502 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3504 "currently only supported on AIX (64-bit mode).");
3512 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3519 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3522 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3533 if (HasAIXSmallLocalDynamicTLS) {
3542 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3555 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3556 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3574 bool is64bit = Subtarget.
isPPC64();
3621 if (!
TM.isPositionIndependent())
3680 PtrVT, GOTPtr, TGA, TGA);
3682 PtrVT, TLSAddr, TGA);
3691 EVT PtrVT =
Op.getValueType();
3716 return getTOCEntry(DAG,
DL, GA);
3719 unsigned MOHiFlag, MOLoFlag;
3727 return getTOCEntry(DAG,
DL, GA);
3739 bool IsStrict =
Op->isStrictFPOpcode();
3742 SDValue LHS =
Op.getOperand(IsStrict ? 1 : 0);
3743 SDValue RHS =
Op.getOperand(IsStrict ? 2 : 1);
3745 EVT LHSVT = LHS.getValueType();
3749 if (LHSVT == MVT::f128) {
3750 assert(!Subtarget.hasP9Vector() &&
3751 "SETCC for f128 is already legal under Power9!");
3762 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3764 if (
Op.getValueType() == MVT::v2i64) {
3767 if (LHS.getValueType() == MVT::v2i64) {
3773 dl, MVT::v4i32, DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, LHS),
3774 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, RHS),
CC);
3775 int ShuffV[] = {1, 0, 3, 2};
3780 dl, MVT::v4i32, Shuff, SetCC32));
3797 if (
C->isAllOnes() ||
C->isZero())
3807 EVT VT =
Op.getValueType();
3816 EVT VT =
Node->getValueType(0);
3830 if (VT == MVT::i64) {
3861 InChain = OverflowArea.
getValue(1);
3907 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3914 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3920 false,
true,
nullptr, std::nullopt,
3929 return Op.getOperand(0);
3936 assert((
Op.getOpcode() == ISD::INLINEASM ||
3937 Op.getOpcode() == ISD::INLINEASM_BR) &&
3938 "Expecting Inline ASM node.");
3948 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3954 unsigned NumVals = Flags.getNumOperandRegisters();
3957 switch (Flags.getKind()) {
3968 for (; NumVals; --NumVals, ++i) {
3970 if (Reg != PPC::LR && Reg != PPC::LR8)
3995 bool isPPC64 = (PtrVT == MVT::i64);
4001 Entry.
Ty = IntPtrTy;
4002 Entry.Node = Trmp;
Args.push_back(Entry);
4005 Entry.Node = DAG.
getConstant(isPPC64 ? 48 : 40, dl,
4006 isPPC64 ? MVT::i64 : MVT::i32);
4007 Args.push_back(Entry);
4009 Entry.Node = FPtr;
Args.push_back(Entry);
4010 Entry.Node = Nest;
Args.push_back(Entry);
4014 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
4018 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
4019 return CallResult.second;
4034 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4069 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4093 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4096 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4098 nextOffset += FrameOffset;
4099 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4102 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4108static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4109 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4110 PPC::F11, PPC::F12, PPC::F13};
4115 unsigned PtrByteSize) {
4117 if (Flags.isByVal())
4118 ArgSize = Flags.getByValSize();
4122 if (!Flags.isInConsecutiveRegs())
4123 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4132 unsigned PtrByteSize) {
4133 Align Alignment(PtrByteSize);
4136 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4137 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4138 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4139 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4140 Alignment =
Align(16);
4143 if (Flags.isByVal()) {
4144 auto BVAlign = Flags.getNonZeroByValAlign();
4145 if (BVAlign > PtrByteSize) {
4146 if (BVAlign.value() % PtrByteSize != 0)
4148 "ByVal alignment is not a multiple of the pointer size");
4150 Alignment = BVAlign;
4155 if (Flags.isInConsecutiveRegs()) {
4159 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4173 unsigned PtrByteSize,
unsigned LinkageSize,
4174 unsigned ParamAreaSize,
unsigned &ArgOffset,
4175 unsigned &AvailableFPRs,
4176 unsigned &AvailableVRs) {
4177 bool UseMemory =
false;
4182 ArgOffset =
alignTo(ArgOffset, Alignment);
4185 if (ArgOffset >= LinkageSize + ParamAreaSize)
4190 if (Flags.isInConsecutiveRegsLast())
4191 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4194 if (ArgOffset > LinkageSize + ParamAreaSize)
4199 if (!Flags.isByVal()) {
4200 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4201 if (AvailableFPRs > 0) {
4205 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4206 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4207 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4208 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4209 if (AvailableVRs > 0) {
4221 unsigned NumBytes) {
4225SDValue PPCTargetLowering::LowerFormalArguments(
4226 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
4230 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4233 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4236 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4240SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4241 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
4282 const Align PtrAlign(4);
4291 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4293 CCInfo.PreAnalyzeFormalArguments(Ins);
4296 CCInfo.clearWasPPCF128();
4298 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4311 RC = &PPC::GPRCRegClass;
4314 if (Subtarget.hasP8Vector())
4315 RC = &PPC::VSSRCRegClass;
4316 else if (Subtarget.hasSPE())
4317 RC = &PPC::GPRCRegClass;
4319 RC = &PPC::F4RCRegClass;
4322 if (Subtarget.hasVSX())
4323 RC = &PPC::VSFRCRegClass;
4324 else if (Subtarget.hasSPE())
4326 RC = &PPC::GPRCRegClass;
4328 RC = &PPC::F8RCRegClass;
4333 RC = &PPC::VRRCRegClass;
4336 RC = &PPC::VRRCRegClass;
4340 RC = &PPC::VRRCRegClass;
4347 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4348 assert(i + 1 < e &&
"No second half of double precision argument");
4360 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4361 if (ValVT == MVT::i1)
4376 ArgOffset += ArgSize - ObjSize;
4394 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4399 unsigned MinReservedArea = CCByValInfo.getStackSize();
4400 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4416 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4417 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4419 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4422 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4425 unsigned NumFPArgRegs = std::size(FPArgRegs);
4434 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4438 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4447 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4451 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4466 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4470 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4483 if (!MemOps.
empty())
4494 const SDLoc &dl)
const {
4498 else if (Flags.isZExt())
4505SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4506 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
4518 "fastcc not supported on varargs functions");
4524 unsigned PtrByteSize = 8;
4528 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4529 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4532 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4533 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4536 const unsigned Num_GPR_Regs = std::size(GPR);
4538 const unsigned Num_VR_Regs = std::size(VR);
4546 bool HasParameterArea = !isELFv2ABI || isVarArg;
4547 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4548 unsigned NumBytes = LinkageSize;
4549 unsigned AvailableFPRs = Num_FPR_Regs;
4550 unsigned AvailableVRs = Num_VR_Regs;
4551 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4552 if (Ins[i].Flags.isNest())
4556 PtrByteSize, LinkageSize, ParamAreaSize,
4557 NumBytes, AvailableFPRs, AvailableVRs))
4558 HasParameterArea =
true;
4565 unsigned ArgOffset = LinkageSize;
4566 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4569 unsigned CurArgIdx = 0;
4570 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4572 bool needsLoad =
false;
4573 EVT ObjectVT =
Ins[ArgNo].VT;
4574 EVT OrigVT =
Ins[ArgNo].ArgVT;
4576 unsigned ArgSize = ObjSize;
4578 if (Ins[ArgNo].isOrigArg()) {
4579 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4580 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4585 unsigned CurArgOffset;
4587 auto ComputeArgOffset = [&]() {
4591 ArgOffset =
alignTo(ArgOffset, Alignment);
4592 CurArgOffset = ArgOffset;
4599 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4600 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4605 if (Flags.isByVal()) {
4606 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4612 ObjSize = Flags.getByValSize();
4613 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4635 if (HasParameterArea ||
4636 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4643 if (ObjSize < PtrByteSize) {
4647 if (!isLittleEndian) {
4653 if (GPR_idx != Num_GPR_Regs) {
4665 ArgOffset += PtrByteSize;
4674 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4675 if (GPR_idx == Num_GPR_Regs)
4686 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4694 ArgOffset += ArgSize;
4703 if (Flags.isNest()) {
4708 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4709 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4717 if (GPR_idx != Num_GPR_Regs) {
4722 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4725 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4731 ArgSize = PtrByteSize;
4742 if (FPR_idx != Num_FPR_Regs) {
4745 if (ObjectVT == MVT::f32)
4747 Subtarget.hasP8Vector()
4748 ? &PPC::VSSRCRegClass
4749 : &PPC::F4RCRegClass);
4752 ? &PPC::VSFRCRegClass
4753 : &PPC::F8RCRegClass);
4768 if (ObjectVT == MVT::f32) {
4769 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4775 ArgVal = DAG.
getNode(ISD::BITCAST, dl, ObjectVT, ArgVal);
4787 ArgSize = Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4788 ArgOffset += ArgSize;
4789 if (Flags.isInConsecutiveRegsLast())
4790 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4804 if (VR_idx != Num_VR_Regs) {
4821 if (ObjSize < ArgSize && !isLittleEndian)
4822 CurArgOffset += ArgSize - ObjSize;
4832 unsigned MinReservedArea;
4833 if (HasParameterArea)
4834 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4836 MinReservedArea = LinkageSize;
4853 int Depth = ArgOffset;
4862 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4863 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4875 if (!MemOps.
empty())
4884 unsigned ParamSize) {
4886 if (!isTailCall)
return 0;
4890 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4892 if (SPDiff < FI->getTailCallSPDelta())
4908 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4921 if (!TM.shouldAssumeDSOLocal(CalleeGV))
4966 if (TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4967 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4970 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4982 const unsigned PtrByteSize = 8;
4986 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4987 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4990 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4991 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4994 const unsigned NumGPRs = std::size(GPR);
4995 const unsigned NumFPRs = 13;
4996 const unsigned NumVRs = std::size(VR);
4997 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4999 unsigned NumBytes = LinkageSize;
5000 unsigned AvailableFPRs = NumFPRs;
5001 unsigned AvailableVRs = NumVRs;
5004 if (Param.Flags.isNest())
continue;
5007 LinkageSize, ParamAreaSize, NumBytes,
5008 AvailableFPRs, AvailableVRs))
5019 auto CalleeArgEnd = CB.
arg_end();
5022 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
5023 const Value* CalleeArg = *CalleeArgIter;
5024 const Value* CallerArg = &(*CallerArgIter);
5025 if (CalleeArg == CallerArg)
5046 CallingConv::ID CalleeCC) {
5048 auto isTailCallableCC = [] (CallingConv::ID
CC){
5051 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5061bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5062 const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
5063 CallingConv::ID CallerCC,
const CallBase *CB,
bool isVarArg,
5066 bool isCalleeExternalSymbol)
const {
5069 if (
DisableSCO && !TailCallOpt)
return false;
5072 if (isVarArg)
return false;
5148bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5149 const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
5150 CallingConv::ID CallerCC,
bool isVarArg,
5182 if (!
C)
return nullptr;
5184 int Addr =
C->getZExtValue();
5185 if ((
Addr & 3) != 0 ||
5191 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5198struct TailCallArgumentInfo {
5203 TailCallArgumentInfo() =
default;
5213 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5214 SDValue Arg = TailCallArgs[i].Arg;
5215 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5216 int FI = TailCallArgs[i].FrameIdx;
5219 Chain, dl, Arg, FIN,
5228 int SPDiff,
const SDLoc &dl) {
5234 bool isPPC64 = Subtarget.
isPPC64();
5235 int SlotSize = isPPC64 ? 8 : 4;
5236 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5238 NewRetAddrLoc,
true);
5239 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5241 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5251 SDValue Arg,
int SPDiff,
unsigned ArgOffset,
5253 int Offset = ArgOffset + SPDiff;
5256 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5258 TailCallArgumentInfo
Info;
5260 Info.FrameIdxOp = FIN;
5268SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5273 EVT VT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5274 LROpOut = getReturnAddrFrameIndex(DAG);
5292 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5300 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5323 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5333 if (!MemOpChains2.
empty())
5357SDValue PPCTargetLowering::LowerCallResult(
5358 SDValue Chain,
SDValue InGlue, CallingConv::ID CallConv,
bool isVarArg,
5365 CCRetInfo.AnalyzeCallResult(
5371 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5377 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5455 bool IsStrictFPCall =
false) {
5459 unsigned RetOpc = 0;
5490 if (IsStrictFPCall) {
5521 auto isLocalCallee = [&]() {
5537 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5554 return getAIXFuncEntryPointSymbolSDNode(GV);
5561 const char *SymName = S->getSymbol();
5568 return getAIXFuncEntryPointSymbolSDNode(
F);
5574 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5582 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5589 assert(Callee.getNode() &&
"What no callee?");
5595 "Expected a CALLSEQ_STARTSDNode.");
5612 SDValue MTCTROps[] = {Chain, Callee, Glue};
5613 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5654 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5669 const MVT RegVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5673 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5674 Alignment, MMOFlags);
5681 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5688 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5700 "Nest parameter is not supported on AIX.");
5716 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5719 const bool IsPPC64 = Subtarget.
isPPC64();
5721 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
5768 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5770 RegsToPass[i].second.getValueType()));
5787 assert(Mask &&
"Missing call preserved mask for calling convention");
5795SDValue PPCTargetLowering::FinishCall(
5810 if (!CFlags.IsIndirect)
5814 dl, CFlags.HasNest, Subtarget);
5824 if (CFlags.IsTailCall) {
5833 "Expecting a global address, external symbol, absolute value, "
5834 "register or an indirect tail call when PC Relative calls are "
5838 "Unexpected call opcode for a tail call.");
5845 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5846 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5858 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5861 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5881 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5882 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5886bool PPCTargetLowering::isEligibleForTCO(
5887 const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
5888 CallingConv::ID CallerCC,
const CallBase *CB,
bool isVarArg,
5891 bool isCalleeExternalSymbol)
const {
5896 return IsEligibleForTailCallOptimization_64SVR4(
5897 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5898 isCalleeExternalSymbol);
5900 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5915 CallingConv::ID CallConv = CLI.
CallConv;
5928 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5943 "Callee should be an llvm::Function object.");
5946 <<
"\nTCO callee: ");
5953 "site marked musttail");
5960 Callee = LowerGlobalAddress(Callee, DAG);
5963 CallConv, isTailCall, isVarArg, isPatchPoint,
5971 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5976 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5978 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5982SDValue PPCTargetLowering::LowerCall_32SVR4(
5992 const CallingConv::ID CallConv = CFlags.CallConv;
5993 const bool IsVarArg = CFlags.IsVarArg;
5994 const bool IsTailCall = CFlags.IsTailCall;
6000 const Align PtrAlign(4);
6025 CCInfo.PreAnalyzeCallOperands(Outs);
6031 unsigned NumArgs = Outs.
size();
6033 for (
unsigned i = 0; i != NumArgs; ++i) {
6034 MVT ArgVT = Outs[i].VT;
6038 if (Outs[i].IsFixed) {
6048 errs() <<
"Call operand #" << i <<
" has unhandled type "
6058 CCInfo.clearWasPPCF128();
6065 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6072 unsigned NumBytes = CCByValInfo.getStackSize();
6086 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6097 bool seenFloatArg =
false;
6102 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6104 ++i, ++RealArgIdx) {
6106 SDValue Arg = OutVals[RealArgIdx];
6109 if (Flags.isByVal()) {
6114 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6137 Chain = CallSeqStart = NewCallSeqStart;
6156 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6163 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6187 if (!MemOpChains.
empty())
6193 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6194 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6195 RegsToPass[i].second, InGlue);
6203 SDValue Ops[] = { Chain, InGlue };
6215 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6216 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6221SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6233 return NewCallSeqStart;
6236SDValue PPCTargetLowering::LowerCall_64SVR4(
6245 unsigned NumOps = Outs.
size();
6246 bool IsSibCall =
false;
6250 unsigned PtrByteSize = 8;
6265 assert(!(IsFastCall && CFlags.IsVarArg) &&
6266 "fastcc not supported on varargs functions");
6273 unsigned NumBytes = LinkageSize;
6274 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6277 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6278 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6281 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6282 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6285 const unsigned NumGPRs = std::size(GPR);
6287 const unsigned NumVRs = std::size(VR);
6293 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6294 if (!HasParameterArea) {
6295 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6296 unsigned AvailableFPRs = NumFPRs;
6297 unsigned AvailableVRs = NumVRs;
6298 unsigned NumBytesTmp = NumBytes;
6299 for (
unsigned i = 0; i != NumOps; ++i) {
6300 if (Outs[i].Flags.isNest())
continue;
6302 PtrByteSize, LinkageSize, ParamAreaSize,
6303 NumBytesTmp, AvailableFPRs, AvailableVRs))
6304 HasParameterArea =
true;
6310 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6315 HasParameterArea =
false;
6318 for (
unsigned i = 0; i != NumOps; ++i) {
6320 EVT ArgVT = Outs[i].VT;
6321 EVT OrigVT = Outs[i].ArgVT;
6327 if (Flags.isByVal()) {
6328 NumGPRsUsed += (Flags.getByValSize()+7)/8;
6329 if (NumGPRsUsed > NumGPRs)
6330 HasParameterArea =
true;
6337 if (++NumGPRsUsed <= NumGPRs)
6347 if (++NumVRsUsed <= NumVRs)
6351 if (++NumVRsUsed <= NumVRs)
6356 if (++NumFPRsUsed <= NumFPRs)
6360 HasParameterArea =
true;
6367 NumBytes =
alignTo(NumBytes, Alignement);
6370 if (Flags.isInConsecutiveRegsLast())
6371 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6374 unsigned NumBytesActuallyUsed = NumBytes;
6384 if (HasParameterArea)
6385 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6387 NumBytes = LinkageSize;
6402 if (CFlags.IsTailCall)
6414 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6425 unsigned ArgOffset = LinkageSize;
6431 for (
unsigned i = 0; i != NumOps; ++i) {
6434 EVT ArgVT = Outs[i].VT;
6435 EVT OrigVT = Outs[i].ArgVT;
6444 auto ComputePtrOff = [&]() {
6448 ArgOffset =
alignTo(ArgOffset, Alignment);
6459 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6460 GPR_idx = std::min(GPR_idx, NumGPRs);
6467 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6473 if (Flags.isByVal()) {
6479 unsigned Size = Flags.getByValSize();
6492 if (GPR_idx != NumGPRs) {
6496 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6498 ArgOffset += PtrByteSize;
6503 if (GPR_idx == NumGPRs &&
Size < 8) {
6505 if (!isLittleEndian) {
6510 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6513 ArgOffset += PtrByteSize;
6522 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6523 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6528 if (
Size < 8 && GPR_idx != NumGPRs) {
6538 if (!isLittleEndian) {
6542 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6550 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6553 ArgOffset += PtrByteSize;
6559 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6562 if (GPR_idx != NumGPRs) {
6563 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6569 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6570 ArgOffset += PtrByteSize;
6572 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6584 if (Flags.isNest()) {
6586 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6593 if (GPR_idx != NumGPRs) {
6594 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6599 assert(HasParameterArea &&
6600 "Parameter area must exist to pass an argument in memory.");
6602 true, CFlags.IsTailCall,
false, MemOpChains,
6603 TailCallArguments, dl);
6605 ArgOffset += PtrByteSize;
6608 ArgOffset += PtrByteSize;
6621 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6622 bool NeededLoad =
false;
6625 if (FPR_idx != NumFPRs)
6626 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6629 if (!NeedGPROrStack)
6631 else if (GPR_idx != NumGPRs && !IsFastCall) {
6642 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i64, Arg);
6645 }
else if (!Flags.isInConsecutiveRegs()) {
6646 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6651 }
else if (ArgOffset % PtrByteSize != 0) {
6653 Lo = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, OutVals[i - 1]);
6654 Hi = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6655 if (!isLittleEndian)
6660 }
else if (Flags.isInConsecutiveRegsLast()) {
6661 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6663 if (!isLittleEndian)
6673 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6681 !isLittleEndian && !Flags.isInConsecutiveRegs()) {
6686 assert(HasParameterArea &&
6687 "Parameter area must exist to pass an argument in memory.");
6689 true, CFlags.IsTailCall,
false, MemOpChains,
6690 TailCallArguments, dl);
6697 if (!IsFastCall || NeededLoad) {
6699 Flags.isInConsecutiveRegs()) ? 4 : 8;
6700 if (Flags.isInConsecutiveRegsLast())
6701 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6721 if (CFlags.IsVarArg) {
6722 assert(HasParameterArea &&
6723 "Parameter area must exist if we have a varargs call.");
6729 if (VR_idx != NumVRs) {
6733 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6736 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6737 if (GPR_idx == NumGPRs)
6744 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6750 if (VR_idx != NumVRs) {
6751 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6756 assert(HasParameterArea &&
6757 "Parameter area must exist to pass an argument in memory.");
6759 true, CFlags.IsTailCall,
true, MemOpChains,
6760 TailCallArguments, dl);
6771 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6772 "mismatch in size of parameter area");
6773 (void)NumBytesActuallyUsed;
6775 if (!MemOpChains.
empty())
6781 if (CFlags.IsIndirect) {
6785 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6800 if (isELFv2ABI && !CFlags.IsPatchPoint)
6801 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6807 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6808 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6809 RegsToPass[i].second, InGlue);
6813 if (CFlags.IsTailCall && !IsSibCall)
6817 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6818 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6825 "Required alignment greater than stack alignment.");
6845 return RequiredAlign <= 8;
6850 return RequiredAlign <= 4;
6859 State.getMachineFunction().getSubtarget());
6860 const bool IsPPC64 = Subtarget.
isPPC64();
6861 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6862 const Align PtrAlign(PtrSize);
6863 const Align StackAlign(16);
6864 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
6866 if (ValVT == MVT::f128)
6873 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6874 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6876 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6877 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6880 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6881 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6882 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6888 if (ByValAlign > StackAlign)
6890 "16 are not supported.");
6893 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6897 if (ByValSize == 0) {
6899 State.getStackSize(), RegVT, LocInfo));
6904 unsigned NextReg = State.getFirstUnallocated(GPRs);
6905 while (NextReg != GPRs.
size() &&
6910 State.AllocateStack(PtrSize, PtrAlign);
6911 assert(Reg &&
"Alocating register unexpectedly failed.");
6913 NextReg = State.getFirstUnallocated(GPRs);
6916 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6917 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6919 if (
MCRegister Reg = State.AllocateReg(GPRs))
6937 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6941 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6946 if (
MCRegister Reg = State.AllocateReg(GPRs))
6960 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6966 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6967 if (
MCRegister Reg = State.AllocateReg(GPRs)) {
6968 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6969 if (State.isVarArg()) {
7001 const unsigned VecSize = 16;
7002 const Align VecAlign(VecSize);
7004 if (!State.isVarArg()) {
7007 if (
MCRegister VReg = State.AllocateReg(VR)) {
7014 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7019 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
7022 while (NextRegIndex != GPRs.
size() &&
7026 State.AllocateStack(PtrSize, PtrAlign);
7027 assert(Reg &&
"Allocating register unexpectedly failed.");
7029 NextRegIndex = State.getFirstUnallocated(GPRs);
7036 if (State.isFixed(ValNo)) {
7037 if (
MCRegister VReg = State.AllocateReg(VR)) {
7040 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7041 State.AllocateReg(GPRs);
7042 State.AllocateStack(VecSize, VecAlign);
7046 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7052 if (NextRegIndex == GPRs.
size()) {
7053 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7061 if (GPRs[NextRegIndex] == PPC::R9) {
7062 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7066 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
7067 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
7068 assert(FirstReg && SecondReg &&
7069 "Allocating R9 or R10 unexpectedly failed.");
7080 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7083 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7084 const MCRegister Reg = State.AllocateReg(GPRs);
7085 assert(Reg &&
"Failed to allocated register for vararg vector argument");
7100 assert((IsPPC64 || SVT != MVT::i64) &&
7101 "i64 should have been split for 32-bit codegen.");
7109 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7111 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7113 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7121 return &PPC::VRRCRegClass;
7134 else if (Flags.isZExt())
7144 if (PPC::GPRCRegClass.
contains(Reg)) {
7145 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7146 "Reg must be a valid argument register!");
7147 return LASize + 4 * (Reg - PPC::R3);
7150 if (PPC::G8RCRegClass.
contains(Reg)) {
7151 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7152 "Reg must be a valid argument register!");
7153 return LASize + 8 * (Reg - PPC::X3);
7199SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7200 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
7206 "Unexpected calling convention!");
7216 const bool IsPPC64 = Subtarget.
isPPC64();
7217 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7229 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7230 uint64_t SaveStackPos = CCInfo.getStackSize();
7232 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7252 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7254 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7266 unsigned StoreSize =
7267 Flags.isByVal() ? Flags.getByValSize() : LocVT.
getStoreSize();
7268 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7271 auto HandleMemLoc = [&]() {
7274 assert((ValSize <= LocSize) &&
7275 "Object size is larger than size of MemLoc");
7278 if (LocSize > ValSize)
7279 CurArgOffset += LocSize - ValSize;
7281 const bool IsImmutable =
7296 assert(isVarArg &&
"Only use custom memloc for vararg.");
7299 const unsigned OriginalValNo = VA.
getValNo();
7300 (void)OriginalValNo;
7302 auto HandleCustomVecRegLoc = [&]() {
7303 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7304 "Missing custom RegLoc.");
7307 "Unexpected Val type for custom RegLoc.");
7309 "ValNo mismatch between custom MemLoc and RegLoc.");
7313 Subtarget.hasVSX()));
7320 HandleCustomVecRegLoc();
7321 HandleCustomVecRegLoc();
7325 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7327 "Only 2 custom RegLocs expected for 64-bit codegen.");
7328 HandleCustomVecRegLoc();
7329 HandleCustomVecRegLoc();
7372 if (Flags.isByVal() && VA.
isMemLoc()) {
7373 const unsigned Size =
7374 alignTo(Flags.getByValSize() ? Flags.getByValSize() : PtrByteSize,
7385 if (Flags.isByVal()) {
7391 const unsigned StackSize =
alignTo(Flags.getByValSize(), PtrByteSize);
7400 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7402 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7415 CopyFrom.
getValue(1), dl, CopyFrom,
7425 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7428 "RegLocs should be for ByVal argument.");
7435 if (
Offset != StackSize) {
7437 "Expected MemLoc for remaining bytes.");
7438 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7452 Subtarget.hasVSX()));
7469 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7471 unsigned CallerReservedArea = std::max<unsigned>(
7472 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7478 CallerReservedArea =
7487 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7488 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7490 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7491 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7492 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7497 for (
unsigned GPRIndex =
7498 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7499 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7502 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7503 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7515 if (!MemOps.
empty())
7521SDValue PPCTargetLowering::LowerCall_AIX(
7534 "Unexpected calling convention!");
7536 if (CFlags.IsPatchPoint)
7543 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7551 const bool IsPPC64 = Subtarget.
isPPC64();
7553 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7554 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7555 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7563 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7564 const unsigned NumBytes = std::max<unsigned>(
7565 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7581 for (
unsigned I = 0, E = ArgLocs.
size();
I != E;) {
7582 const unsigned ValNo = ArgLocs[
I].getValNo();
7586 if (Flags.isByVal()) {
7587 const unsigned ByValSize = Flags.getByValSize();
7595 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7604 unsigned LoadOffset = 0;
7607 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7610 LoadOffset += PtrByteSize;
7613 "Unexpected location for pass-by-value argument.");
7617 if (LoadOffset == ByValSize)
7621 assert(ArgLocs[
I].getValNo() == ValNo &&
7622 "Expected additional location for by-value argument.");
7624 if (ArgLocs[
I].isMemLoc()) {
7625 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7630 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7636 CallSeqStart, MemcpyFlags, DAG, dl);
7645 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7646 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7647 "Unexpected register residue for by-value argument.");
7649 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7653 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7663 "Unexpected load emitted during handling of pass-by-value "
7671 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7706 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7714 const unsigned OriginalValNo = VA.
getValNo();
7716 unsigned LoadOffset = 0;
7717 auto HandleCustomVecRegLoc = [&]() {
7718 assert(
I != E &&
"Unexpected end of CCvalAssigns.");
7719 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7720 "Expected custom RegLoc.");
7723 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7729 LoadOffset += PtrByteSize;
7735 HandleCustomVecRegLoc();
7736 HandleCustomVecRegLoc();
7738 if (
I != E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7739 ArgLocs[
I].getValNo() == OriginalValNo) {
7741 "Only 2 custom RegLocs expected for 64-bit codegen.");
7742 HandleCustomVecRegLoc();
7743 HandleCustomVecRegLoc();
7761 "Unexpected register handling for calling convention.");
7767 "Custom register handling only expected for VarArg.");
7772 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7776 else if (Arg.getValueType().getFixedSizeInBits() <
7784 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7785 "Unexpected custom register for argument!");
7806 if (!MemOpChains.
empty())
7811 if (CFlags.IsIndirect) {
7812 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7815 const MVT PtrVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
7816 const unsigned TOCSaveOffset =
7832 for (
auto Reg : RegsToPass) {
7833 Chain = DAG.
getCopyToReg(Chain, dl, Reg.first, Reg.second, InGlue);
7837 const int SPDiff = 0;
7838 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7839 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7843PPCTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
7848 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7849 return CCInfo.CheckReturn(
7856PPCTargetLowering::LowerReturn(
SDValue Chain, CallingConv::ID CallConv,
7864 CCInfo.AnalyzeReturn(Outs,
7873 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7877 SDValue Arg = OutVals[RealResIdx];
7892 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7915 RetOps.push_back(Glue);
7921PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7926 EVT IntVT =
Op.getValueType();
7930 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7932 SDValue Ops[2] = {Chain, FPSIdx};
7946 bool isPPC64 = Subtarget.
isPPC64();
7947 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7967 bool isPPC64 = Subtarget.
isPPC64();
7988PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7990 bool isPPC64 = Subtarget.
isPPC64();
8024 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8025 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
8036 bool isPPC64 = Subtarget.
isPPC64();
8048 Op.getOperand(0),
Op.getOperand(1));
8055 Op.getOperand(0),
Op.getOperand(1));
8059 if (
Op.getValueType().isVector())
8060 return LowerVectorLoad(
Op, DAG);
8062 assert(
Op.getValueType() == MVT::i1 &&
8063 "Custom lowering only for i1 loads");
8076 BasePtr, MVT::i8, MMO);
8084 if (
Op.getOperand(1).getValueType().isVector())
8085 return LowerVectorStore(
Op, DAG);
8087 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8088 "Custom lowering only for i1 stores");
8107 assert(
Op.getValueType() == MVT::i1 &&
8108 "Custom lowering only for i1 results");
8136 EVT TrgVT =
Op.getValueType();
8160 if (SrcSize == 256) {
8171 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8179 for (
unsigned i = 0; i < TrgNumElts; ++i)
8182 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8186 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8190 Op1 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op1);
8191 Op2 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op2);
8199 EVT ResVT =
Op.getValueType();
8200 EVT CmpVT =
Op.getOperand(0).getValueType();
8201 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
8202 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8208 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8225 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8257 if (LHS.getValueType() == MVT::f32)
8258 LHS = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, LHS);
8261 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8263 DAG.
getNode(ISD::FNEG, dl, MVT::f64, LHS), Sel1, FV);
8270 if (LHS.getValueType() == MVT::f32)
8271 LHS = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, LHS);
8279 if (LHS.getValueType() == MVT::f32)
8280 LHS = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, LHS);
8282 DAG.
getNode(ISD::FNEG, dl, MVT::f64, LHS), TV, FV);
8293 if (
Cmp.getValueType() == MVT::f32)
8294 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8297 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8299 DAG.
getNode(ISD::FNEG, dl, MVT::f64, Cmp), Sel1, FV);
8303 if (
Cmp.getValueType() == MVT::f32)
8304 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8309 if (
Cmp.getValueType() == MVT::f32)
8310 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8315 if (
Cmp.getValueType() == MVT::f32)
8316 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8321 if (
Cmp.getValueType() == MVT::f32)
8322 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8354 bool IsStrict =
Op->isStrictFPOpcode();
8363 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8365 MVT DestTy =
Op.getSimpleValueType();
8366 assert(Src.getValueType().isFloatingPoint() &&
8367 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8368 DestTy == MVT::i64) &&
8369 "Invalid FP_TO_INT types");
8370 if (Src.getValueType() == MVT::f32) {
8374 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8375 Chain = Src.getValue(1);
8377 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
8379 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8380 DestTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
8389 assert((IsSigned || Subtarget.hasFPCVT()) &&
8390 "i64 FP_TO_UINT is supported only with FPCVT");
8393 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8397 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8400 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8405void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8407 const SDLoc &dl)
const {
8411 bool IsStrict =
Op->isStrictFPOpcode();
8414 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8415 (IsSigned || Subtarget.hasFPCVT());
8426 Alignment =
Align(4);
8429 SDValue Ops[] = { Chain, Tmp, FIPtr };
8431 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8433 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8437 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8446 RLI.Alignment = Alignment;
8454 const SDLoc &dl)
const {
8457 if (
Op->isStrictFPOpcode())
8464 const SDLoc &dl)
const {
8465 bool IsStrict =
Op->isStrictFPOpcode();
8468 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8469 EVT SrcVT = Src.getValueType();
8470 EVT DstVT =
Op.getValueType();
8473 if (SrcVT == MVT::f128)
8474 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8478 if (SrcVT == MVT::ppcf128) {
8479 if (DstVT == MVT::i32) {
8495 {Op.getOperand(0), Lo, Hi}, Flags);
8498 {Res.getValue(1), Res}, Flags);
8504 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8528 {Chain, Src, FltOfs}, Flags);
8532 {Chain, Val}, Flags);
8535 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8553 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8554 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8557 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8559 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8560 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8571bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8576 if (
Op->isStrictFPOpcode())
8581 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8585 Op.getOperand(0).getValueType())) {
8587 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8592 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8593 LD->isNonTemporal())
8595 if (
LD->getMemoryVT() != MemVT)
8605 RLI.Ptr =
LD->getBasePtr();
8606 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8608 "Non-pre-inc AM on PPC?");
8613 RLI.Chain =
LD->getChain();
8614 RLI.MPI =
LD->getPointerInfo();
8615 RLI.IsDereferenceable =
LD->isDereferenceable();
8616 RLI.IsInvariant =
LD->isInvariant();
8617 RLI.Alignment =
LD->getAlign();
8618 RLI.AAInfo =
LD->getAAInfo();
8619 RLI.Ranges =
LD->getRanges();
8621 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8629void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8635 SDLoc dl(NewResChain);
8638 NewResChain, DAG.
getUNDEF(MVT::Other));
8640 "A new TF really is required here");
8649bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8650 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8657 if (!Subtarget.hasP9Vector() &&
8666 if (UI.getUse().get().getResNo() != 0)
8692 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8695 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8696 if (
Op->isStrictFPOpcode()) {
8698 Chain =
Op.getOperand(0);
8700 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8702 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8710 const SDLoc &dl)
const {
8711 assert((
Op.getValueType() == MVT::f32 ||
8712 Op.getValueType() == MVT::f64) &&
8713 "Invalid floating point type as target of conversion");
8714 assert(Subtarget.hasFPCVT() &&
8715 "Int to FP conversions with direct moves require FPCVT");
8716 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8717 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8739 for (
unsigned i = 1; i < NumConcat; ++i)
8746 const SDLoc &dl)
const {
8747 bool IsStrict =
Op->isStrictFPOpcode();
8748 unsigned Opc =
Op.getOpcode();
8749 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8752 "Unexpected conversion type");
8753 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8754 "Supports conversions to v2f64/v4f32 only.");
8761 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8766 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8769 for (
unsigned i = 0; i < WideNumElts; ++i)
8772 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8773 int SaveElts = FourEltRes ? 4 : 2;
8775 for (
int i = 0; i < SaveElts; i++)
8776 ShuffV[i * Stride] = i;
8778 for (
int i = 1; i <= SaveElts; i++)
8779 ShuffV[i * Stride - 1] = i - 1;
8787 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8788 EVT ExtVT = Src.getValueType();
8789 if (Subtarget.hasP9Altivec())
8796 Extend = DAG.
getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);
8800 {Op.getOperand(0), Extend}, Flags);
8802 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8810 bool IsStrict =
Op->isStrictFPOpcode();
8811 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8818 EVT InVT = Src.getValueType();
8819 EVT OutVT =
Op.getValueType();
8822 return LowerINT_TO_FPVector(
Op, DAG, dl);
8825 if (
Op.getValueType() == MVT::f128)
8826 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8829 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8832 if (Src.getValueType() == MVT::i1) {
8844 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8845 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8846 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8848 assert((IsSigned || Subtarget.hasFPCVT()) &&
8849 "UINT_TO_FP is supported only with FPCVT");
8851 if (Src.getValueType() == MVT::i64) {
8863 if (
Op.getValueType() == MVT::f32 &&
8864 !Subtarget.hasFPCVT() &&
8905 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8906 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8907 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8908 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8909 }
else if (Subtarget.hasLFIWAX() &&
8910 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8913 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8914 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8917 Ops, MVT::i32, MMO);
8918 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8919 }
else if (Subtarget.hasFPCVT() &&
8920 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8923 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8924 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8927 Ops, MVT::i32, MMO);
8928 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8929 }
else if (((Subtarget.hasLFIWAX() &&
8931 (Subtarget.hasFPCVT() &&
8946 "Expected an i32 store");
8952 RLI.Alignment =
Align(4);
8956 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8957 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8960 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8961 Ops, MVT::i32, MMO);
8962 Chain =
Bits.getValue(1);
8964 Bits = DAG.
getNode(ISD::BITCAST, dl, MVT::f64, SINT);
8970 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8974 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8982 assert(Src.getValueType() == MVT::i32 &&
8983 "Unhandled INT_TO_FP type in custom expander!");
8993 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8996 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9006 "Expected an i32 store");
9012 RLI.Alignment =
Align(4);
9017 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9018 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
9020 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
9024 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
9027 "i32->FP without LFIWAX supported only on PPC64");
9036 Chain, dl, Ext64, FIdx,
9042 MVT::f64, dl, Chain, FIdx,
9051 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9055 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
9072 uint64_t Mode = CVal->getZExtValue();
9073 assert(Mode < 4 &&
"Unsupported rounding mode!");
9074 unsigned InternalRnd = Mode ^ (~(Mode >> 1) & 1);
9075 if (Subtarget.isISA3_0())
9078 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9079 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9082 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9083 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9085 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9103 if (!Subtarget.isISA3_0()) {
9105 Chain =
MFFS.getValue(1);
9109 if (Subtarget.isISA3_0()) {
9114 PPC::RLDIMI, Dl, MVT::i64,
9115 {DAG.
getNode(ISD::BITCAST, Dl, MVT::i64, MFFS),
9119 NewFPSCR =
SDValue(InsertRN, 0);
9121 NewFPSCR = DAG.
getNode(ISD::BITCAST, Dl, MVT::f64, NewFPSCR);
9130 if (Subtarget.isISA3_0()) {
9138 PPC::RLWIMI, Dl, MVT::i32,
9139 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9140 DAG.getTargetConstant(30, Dl, MVT::i32),
9141 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9149 if (Subtarget.isISA3_0())
9155 PPC::MTFSF, Dl, MVT::Other,
9183 EVT VT =
Op.getValueType();
9189 Chain =
MFFS.getValue(1);
9194 DAG.
getNode(ISD::BITCAST, dl, MVT::i64, MFFS));
9203 "Stack slot adjustment is valid only on big endian subtargets!");
9233 EVT VT =
Op.getValueType();
9237 VT ==
Op.getOperand(1).getValueType() &&
9257 SDValue OutOps[] = { OutLo, OutHi };
9262 EVT VT =
Op.getValueType();
9266 VT ==
Op.getOperand(1).getValueType() &&
9286 SDValue OutOps[] = { OutLo, OutHi };
9292 EVT VT =
Op.getValueType();
9295 VT ==
Op.getOperand(1).getValueType() &&
9315 SDValue OutOps[] = { OutLo, OutHi };
9322 EVT VT =
Op.getValueType();
9329 EVT AmtVT =
Z.getValueType();
9352 static const MVT VTys[] = {
9353 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9356 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9359 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9364 EVT CanonicalVT = VTys[SplatSize-1];
9373 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9374 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9383 EVT DestVT = MVT::Other) {
9393 EVT DestVT = MVT::Other) {
9396 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9404 LHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, LHS);
9405 RHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, RHS);
9408 for (
unsigned i = 0; i != 16; ++i)
9411 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
9429 EVT VecVT = V->getValueType(0);
9430 bool RightType = VecVT == MVT::v2f64 ||
9431 (HasP8Vector && VecVT == MVT::v4f32) ||
9432 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9436 bool IsSplat =
true;
9437 bool IsLoad =
false;
9443 if (V->isConstant())
9445 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9446 if (V->getOperand(i).isUndef())
9450 if (V->getOperand(i).getOpcode() == ISD::LOAD ||
9452 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9454 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9456 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD))
9460 if (V->getOperand(i) != Op0 ||
9461 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9464 return !(IsSplat && IsLoad);
9474 (
Op.getValueType() != MVT::f128))
9479 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9490 while (InputLoad->
getOpcode() == ISD::BITCAST)
9497 if (InputLoad->
getOpcode() != ISD::LOAD)
9507 APFloat APFloatToConvert = ArgAPFloat;
9508 bool LosesInfo =
true;
9513 ArgAPFloat = APFloatToConvert;
9535 APFloat APFloatToConvert = ArgAPFloat;
9536 bool LosesInfo =
true;
9540 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9549 EVT Ty =
Op->getValueType(0);
9552 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9561 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9565 if (Ty == MVT::v2i64) {
9568 if (MemVT == MVT::i32) {
9588 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9591 APInt APSplatBits, APSplatUndef;
9592 unsigned SplatBitSize;
9594 bool BVNIsConstantSplat =
9602 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9603 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9606 if ((
Op->getValueType(0) == MVT::v2f64) &&
9639 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9646 const SDValue *InputLoad = &
Op.getOperand(0);
9651 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9652 unsigned ElementSize =
9655 assert(((ElementSize == 2 * MemorySize)
9659 "Unmatched element size and opcode!\n");
9664 unsigned NumUsesOfInputLD = 128 / ElementSize;
9666 if (BVInOp.isUndef())
9681 if (NumUsesOfInputLD == 1 &&
9684 Subtarget.hasLFIWAX()))
9693 Subtarget.isISA3_1() && ElementSize <= 16)
9696 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9698 Subtarget.hasVSX()) {
9705 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9706 LD->getMemoryVT(),
LD->getMemOperand());
9718 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9720 Subtarget.hasP8Vector()))
9727 unsigned SplatSize = SplatBitSize / 8;
9732 if (SplatBits == 0) {
9734 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9736 Op = DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Z);
9746 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9748 Op.getValueType(), DAG, dl);
9750 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9755 if (Subtarget.hasP9Vector() && SplatSize == 1)
9760 int32_t SextVal =
SignExtend32(SplatBits, SplatBitSize);
9761 if (SextVal >= -16 && SextVal <= 15)
9774 if (SextVal >= -32 && SextVal <= 31) {
9779 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9780 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9783 if (VT ==
Op.getValueType())
9786 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), RetVal);
9792 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9802 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9806 static const signed char SplatCsts[] = {
9807 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9808 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9811 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9814 int i = SplatCsts[idx];
9818 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9821 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9823 static const unsigned IIDs[] = {
9824 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9825 Intrinsic::ppc_altivec_vslw
9828 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9832 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9834 static const unsigned IIDs[] = {
9835 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9836 Intrinsic::ppc_altivec_vsrw
9839 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9843 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9844 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9846 static const unsigned IIDs[] = {
9847 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9848 Intrinsic::ppc_altivec_vrlw
9851 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9855 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9861 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9867 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9882 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9883 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9884 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9900 if (LHSID == (1*9+2)*9+3)
return LHS;
9901 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9913 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9914 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9915 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9916 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9919 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9920 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9921 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9922 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9925 for (
unsigned i = 0; i != 16; ++i)
9926 ShufIdxs[i] = (i&3)+0;
9929 for (
unsigned i = 0; i != 16; ++i)
9930 ShufIdxs[i] = (i&3)+4;
9933 for (
unsigned i = 0; i != 16; ++i)
9934 ShufIdxs[i] = (i&3)+8;
9937 for (
unsigned i = 0; i != 16; ++i)
9938 ShufIdxs[i] = (i&3)+12;
9948 OpLHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpLHS);
9949 OpRHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpRHS);
9951 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
9959 const unsigned BytesInVector = 16;
9964 unsigned ShiftElts = 0, InsertAtByte = 0;
9968 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9969 0, 15, 14, 13, 12, 11, 10, 9};
9970 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9971 1, 2, 3, 4, 5, 6, 7, 8};
9974 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9986 bool FoundCandidate =
false;
9990 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9993 for (
unsigned i = 0; i < BytesInVector; ++i) {
9994 unsigned CurrentElement =
Mask[i];
9997 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
10000 bool OtherElementsInOrder =
true;
10003 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10010 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10011 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10012 OtherElementsInOrder =
false;
10019 if (OtherElementsInOrder) {
10021 if (
V2.isUndef()) {
10026 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10027 : BigEndianShifts[CurrentElement & 0xF];
10028 Swap = CurrentElement < BytesInVector;
10030 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10031 FoundCandidate =
true;
10036 if (!FoundCandidate)
10060 const unsigned NumHalfWords = 8;
10061 const unsigned BytesInVector = NumHalfWords * 2;
10070 unsigned ShiftElts = 0, InsertAtByte = 0;
10074 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10075 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10078 uint32_t OriginalOrderLow = 0x1234567;
10079 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10082 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10083 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10100 bool FoundCandidate =
false;
10103 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10104 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10112 if (
V2.isUndef()) {
10114 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10115 TargetOrder = OriginalOrderLow;
10119 if (MaskOneElt == VINSERTHSrcElem &&
10120 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10121 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10122 FoundCandidate =
true;
10128 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10130 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10132 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10133 : BigEndianShifts[MaskOneElt & 0x7];
10134 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10135 Swap = MaskOneElt < NumHalfWords;
10136 FoundCandidate =
true;
10142 if (!FoundCandidate)
10159 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10164 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10177 auto ShuffleMask = SVN->
getMask();
10192 ShuffleMask = CommutedSV->
getMask();
10201 APInt APSplatValue, APSplatUndef;
10202 unsigned SplatBitSize;
10218 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10219 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10220 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10222 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10223 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10224 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10232 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10233 SplatVal |= (SplatVal << SplatBitSize);
10238 return DAG.
getNode(ISD::BITCAST,
DL, MVT::v16i8, SplatNode);
10247 assert(
Op.getValueType() == MVT::v1i128 &&
10248 "Only set v1i128 as custom, other type shouldn't reach here!");
10253 if (SHLAmt % 8 == 0) {
10254 std::array<int, 16>
Mask;
10255 std::iota(
Mask.begin(),
Mask.end(), 0);
10256 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10260 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, Shuffle);
10268 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, OROp);
10285 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10290 V1 =
Op.getOperand(0);
10291 V2 =
Op.getOperand(1);
10293 EVT VT =
Op.getValueType();
10296 unsigned ShiftElts, InsertAtByte;
10302 bool IsPermutedLoad =
false;
10304 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10314 if (IsPermutedLoad) {
10315 assert((isLittleEndian || IsFourByte) &&
10316 "Unexpected size for permuted load on big endian target");
10317 SplatIdx += IsFourByte ? 2 : 1;
10318 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10319 "Splat of a value outside of the loaded memory");
10324 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10327 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10329 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10333 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10346 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10349 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10358 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10361 if (Subtarget.hasP9Vector() &&
10375 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10379 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10382 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10384 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10385 return SplatInsertNode;
10388 if (Subtarget.hasP9Altivec()) {
10390 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10393 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10397 if (Subtarget.hasVSX() &&
10403 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32,
V2.isUndef() ? V1 : V2);
10407 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Shl);
10410 if (Subtarget.hasVSX() &&
10416 DAG.
getNode(ISD::BITCAST, dl, MVT::v2i64,
V2.isUndef() ? V1 : V2);
10420 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, PermDI);
10423 if (Subtarget.hasP9Vector()) {
10427 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveHWord);
10431 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveWord);
10435 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveDWord);
10439 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveQWord);
10443 if (Subtarget.hasVSX()) {
10450 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8,
Splat);
10457 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Swap);
10464 if (
V2.isUndef()) {
10477 (Subtarget.hasP8Altivec() && (
10488 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10498 (Subtarget.hasP8Altivec() && (
10509 unsigned PFIndexes[4];
10510 bool isFourElementShuffle =
true;
10511 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10513 unsigned EltNo = 8;
10514 for (
unsigned j = 0;
j != 4; ++
j) {
10515 if (PermMask[i * 4 + j] < 0)
10518 unsigned ByteSource = PermMask[i * 4 +
j];
10519 if ((ByteSource & 3) != j) {
10520 isFourElementShuffle =
false;
10525 EltNo = ByteSource / 4;
10526 }
else if (EltNo != ByteSource / 4) {
10527 isFourElementShuffle =
false;
10531 PFIndexes[i] = EltNo;
10539 if (isFourElementShuffle) {
10541 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10542 PFIndexes[2] * 9 + PFIndexes[3];
10545 unsigned Cost = (PFEntry >> 30);
10565 if (
V2.isUndef())
V2 = V1;
10567 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10576 bool NeedSwap =
false;
10578 bool isPPC64 = Subtarget.
isPPC64();
10580 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10582 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10583 "XXPERM instead\n");
10589 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10590 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10592 NeedSwap = !NeedSwap;
10627 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10629 if (V1HasXXSWAPD) {
10632 else if (SrcElt < 16)
10635 if (V2HasXXSWAPD) {
10638 else if (SrcElt > 15)
10647 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10648 if (isLittleEndian)
10650 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10653 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10656 if (V1HasXXSWAPD) {
10660 if (V2HasXXSWAPD) {
10661 dl =
SDLoc(
V2->getOperand(0));
10662 V2 =
V2->getOperand(0)->getOperand(1);
10665 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10666 if (ValType != MVT::v2f64)
10668 if (
V2.getValueType() != MVT::v2f64)
10672 ShufflesHandledWithVPERM++;
10677 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10679 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10682 dbgs() <<
"With the following permute control vector:\n";
10687 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10691 if (isLittleEndian)
10697 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10709 switch (IntrinsicID) {
10713 case Intrinsic::ppc_altivec_vcmpbfp_p:
10717 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10721 case Intrinsic::ppc_altivec_vcmpequb_p:
10725 case Intrinsic::ppc_altivec_vcmpequh_p:
10729 case Intrinsic::ppc_altivec_vcmpequw_p:
10733 case Intrinsic::ppc_altivec_vcmpequd_p:
10734 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10740 case Intrinsic::ppc_altivec_vcmpneb_p:
10741 case Intrinsic::ppc_altivec_vcmpneh_p:
10742 case Intrinsic::ppc_altivec_vcmpnew_p:
10743 case Intrinsic::ppc_altivec_vcmpnezb_p:
10744 case Intrinsic::ppc_altivec_vcmpnezh_p:
10745 case Intrinsic::ppc_altivec_vcmpnezw_p:
10746 if (Subtarget.hasP9Altivec()) {
10747 switch (IntrinsicID) {
10750 case Intrinsic::ppc_altivec_vcmpneb_p:
10753 case Intrinsic::ppc_altivec_vcmpneh_p:
10756 case Intrinsic::ppc_altivec_vcmpnew_p:
10759 case Intrinsic::ppc_altivec_vcmpnezb_p:
10762 case Intrinsic::ppc_altivec_vcmpnezh_p:
10765 case Intrinsic::ppc_altivec_vcmpnezw_p:
10773 case Intrinsic::ppc_altivec_vcmpgefp_p:
10777 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10781 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10785 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10789 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10793 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10794 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10800 case Intrinsic::ppc_altivec_vcmpgtub_p:
10804 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10808 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10812 case Intrinsic::ppc_altivec_vcmpgtud_p:
10813 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10820 case Intrinsic::ppc_altivec_vcmpequq:
10821 case Intrinsic::ppc_altivec_vcmpgtsq:
10822 case Intrinsic::ppc_altivec_vcmpgtuq:
10823 if (!Subtarget.isISA3_1())
10825 switch (IntrinsicID) {
10828 case Intrinsic::ppc_altivec_vcmpequq:
10831 case Intrinsic::ppc_altivec_vcmpgtsq:
10834 case Intrinsic::ppc_altivec_vcmpgtuq:
10841 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10842 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10843 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10844 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10845 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10846 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10847 if (Subtarget.hasVSX()) {
10848 switch (IntrinsicID) {
10849 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10852 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10855 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10858 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10861 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10864 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10874 case Intrinsic::ppc_altivec_vcmpbfp:
10877 case Intrinsic::ppc_altivec_vcmpeqfp:
10880 case Intrinsic::ppc_altivec_vcmpequb:
10883 case Intrinsic::ppc_altivec_vcmpequh:
10886 case Intrinsic::ppc_altivec_vcmpequw:
10889 case Intrinsic::ppc_altivec_vcmpequd:
10890 if (Subtarget.hasP8Altivec())
10895 case Intrinsic::ppc_altivec_vcmpneb:
10896 case Intrinsic::ppc_altivec_vcmpneh:
10897 case Intrinsic::ppc_altivec_vcmpnew:
10898 case Intrinsic::ppc_altivec_vcmpnezb:
10899 case Intrinsic::ppc_altivec_vcmpnezh:
10900 case Intrinsic::ppc_altivec_vcmpnezw:
10901 if (Subtarget.hasP9Altivec())
10902 switch (IntrinsicID) {
10905 case Intrinsic::ppc_altivec_vcmpneb:
10908 case Intrinsic::ppc_altivec_vcmpneh:
10911 case Intrinsic::ppc_altivec_vcmpnew:
10914 case Intrinsic::ppc_altivec_vcmpnezb:
10917 case Intrinsic::ppc_altivec_vcmpnezh:
10920 case Intrinsic::ppc_altivec_vcmpnezw:
10927 case Intrinsic::ppc_altivec_vcmpgefp:
10930 case Intrinsic::ppc_altivec_vcmpgtfp:
10933 case Intrinsic::ppc_altivec_vcmpgtsb:
10936 case Intrinsic::ppc_altivec_vcmpgtsh:
10939 case Intrinsic::ppc_altivec_vcmpgtsw:
10942 case Intrinsic::ppc_altivec_vcmpgtsd:
10943 if (Subtarget.hasP8Altivec())
10948 case Intrinsic::ppc_altivec_vcmpgtub:
10951 case Intrinsic::ppc_altivec_vcmpgtuh:
10954 case Intrinsic::ppc_altivec_vcmpgtuw:
10957 case Intrinsic::ppc_altivec_vcmpgtud:
10958 if (Subtarget.hasP8Altivec())
10963 case Intrinsic::ppc_altivec_vcmpequq_p:
10964 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10965 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10966 if (!Subtarget.isISA3_1())
10968 switch (IntrinsicID) {
10971 case Intrinsic::ppc_altivec_vcmpequq_p:
10974 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10977 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10991 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
10995 switch (IntrinsicID) {
10996 case Intrinsic::thread_pointer:
11002 case Intrinsic::ppc_rldimi: {
11003 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
11007 return Op.getOperand(2);
11008 if (
Mask.isAllOnes())
11011 unsigned MB = 0, ME = 0;
11015 if (ME < 63 - SH) {
11018 }
else if (ME > 63 - SH) {
11024 {Op.getOperand(2), Src,
11025 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11026 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11030 case Intrinsic::ppc_rlwimi: {
11033 return Op.getOperand(2);
11034 if (
Mask.isAllOnes())
11037 unsigned MB = 0, ME = 0;
11041 PPC::RLWIMI, dl, MVT::i32,
11042 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11043 DAG.getTargetConstant(MB, dl, MVT::i32),
11044 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11048 case Intrinsic::ppc_rlwnm: {
11049 if (
Op.getConstantOperandVal(3) == 0)
11051 unsigned MB = 0, ME = 0;
11056 {Op.getOperand(1), Op.getOperand(2),
11057 DAG.getTargetConstant(MB, dl, MVT::i32),
11058 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11062 case Intrinsic::ppc_mma_disassemble_acc: {
11063 if (Subtarget.isISAFuture()) {
11064 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11102 case Intrinsic::ppc_vsx_disassemble_pair: {
11105 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11110 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11121 case Intrinsic::ppc_mma_xxmfacc:
11122 case Intrinsic::ppc_mma_xxmtacc: {
11124 if (!Subtarget.isISAFuture())
11135 case Intrinsic::ppc_unpack_longdouble: {
11137 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11138 "Argument of long double unpack must be 0 or 1!");
11141 Idx->getValueType(0)));
11144 case Intrinsic::ppc_compare_exp_lt:
11145 case Intrinsic::ppc_compare_exp_gt:
11146 case Intrinsic::ppc_compare_exp_eq:
11147 case Intrinsic::ppc_compare_exp_uo: {
11149 switch (IntrinsicID) {
11150 case Intrinsic::ppc_compare_exp_lt:
11153 case Intrinsic::ppc_compare_exp_gt:
11156 case Intrinsic::ppc_compare_exp_eq:
11159 case Intrinsic::ppc_compare_exp_uo:
11165 PPC::SELECT_CC_I4, dl, MVT::i32,
11166 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11167 Op.getOperand(1), Op.getOperand(2)),
11169 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11170 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11173 case Intrinsic::ppc_test_data_class: {
11174 EVT OpVT =
Op.getOperand(1).getValueType();
11175 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11176 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11180 PPC::SELECT_CC_I4, dl, MVT::i32,
11181 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11184 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11185 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11188 case Intrinsic::ppc_fnmsub: {
11189 EVT VT =
Op.getOperand(1).getValueType();
11190 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11194 DAG.
getNode(ISD::FNEG, dl, VT,
Op.getOperand(3))));
11196 Op.getOperand(2),
Op.getOperand(3));
11198 case Intrinsic::ppc_convert_f128_to_ppcf128:
11199 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11200 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11201 ? RTLIB::CONVERT_PPCF128_F128
11202 : RTLIB::CONVERT_F128_PPCF128;
11203 MakeLibCallOptions CallOptions;
11204 std::pair<SDValue, SDValue>
Result =
11205 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11209 case Intrinsic::ppc_maxfe:
11210 case Intrinsic::ppc_maxfl:
11211 case Intrinsic::ppc_maxfs:
11212 case Intrinsic::ppc_minfe:
11213 case Intrinsic::ppc_minfl:
11214 case Intrinsic::ppc_minfs: {
11215 EVT VT =
Op.getValueType();
11218 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
11219 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11222 if (IntrinsicID == Intrinsic::ppc_minfe ||
11223 IntrinsicID == Intrinsic::ppc_minfl ||
11224 IntrinsicID == Intrinsic::ppc_minfs)
11246 Op.getOperand(1),
Op.getOperand(2),
11248 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Tmp);
11257 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11269 switch (
Op.getConstantOperandVal(1)) {
11272 BitNo = 0; InvertBit =
false;
11275 BitNo = 0; InvertBit =
true;
11278 BitNo = 2; InvertBit =
false;
11281 BitNo = 2; InvertBit =
true;
11305 switch (
Op.getConstantOperandVal(ArgStart)) {
11306 case Intrinsic::ppc_cfence: {
11307 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11308 SDValue Val =
Op.getOperand(ArgStart + 1);
11310 if (Ty == MVT::i128) {
11315 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11316 EVT FTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
11340 int VectorIndex = 0;
11352 assert(
Op.getOpcode() == ISD::ATOMIC_CMP_SWAP &&
11353 "Expecting an atomic compare-and-swap here.");
11356 EVT MemVT = AtomicNode->getMemoryVT();
11374 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11375 Ops.
push_back(AtomicNode->getOperand(i));
11387 EVT MemVT =
N->getMemoryVT();
11389 "Expect quadword atomic operations");
11391 unsigned Opc =
N->getOpcode();
11393 case ISD::ATOMIC_LOAD: {
11399 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11400 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11403 Ops, MemVT,
N->getMemOperand());
11410 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11414 case ISD::ATOMIC_STORE: {
11420 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11430 N->getMemOperand());
11442 enum DataClassMask {
11444 DC_NEG_INF = 1 << 4,
11445 DC_POS_INF = 1 << 5,
11446 DC_NEG_ZERO = 1 << 2,
11447 DC_POS_ZERO = 1 << 3,
11448 DC_NEG_SUBNORM = 1,
11449 DC_POS_SUBNORM = 1 << 1,
11452 EVT VT =
Op.getValueType();
11454 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11455 : VT == MVT::f64 ? PPC::XSTSTDCDP
11466 return DAG.
getNOT(Dl, Rev, MVT::i1);
11473 TestOp, Dl, MVT::i32,
11475 DC_NEG_ZERO | DC_POS_ZERO |
11476 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11482 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11488 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11493 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11506 bool IsQuiet = Mask &
fcQNan;
11512 if (VT == MVT::f128) {
11516 QuietMask = 0x8000;
11517 }
else if (VT == MVT::f64) {
11529 QuietMask = 0x80000;
11530 }
else if (VT == MVT::f32) {
11532 QuietMask = 0x400000;
11548 unsigned NativeMask = 0;
11550 NativeMask |= DC_NAN;
11552 NativeMask |= DC_NEG_INF;
11554 NativeMask |= DC_POS_INF;
11556 NativeMask |= DC_NEG_ZERO;
11558 NativeMask |= DC_POS_ZERO;
11560 NativeMask |= DC_NEG_SUBNORM;
11562 NativeMask |= DC_POS_SUBNORM;
11565 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11567 TestOp, Dl, MVT::i32,
11576 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11578 uint64_t RHSC =
Op.getConstantOperandVal(1);
11581 if (LHS.getValueType() == MVT::ppcf128) {
11597 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11598 Op.getValueType() == MVT::v4i32 && Op0.
getOpcode() == ISD::LOAD &&
11604 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11609 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
11610 return Bits.getValue(0);
11632 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11639 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11653 "Should only be called for ISD::INSERT_VECTOR_ELT");
11657 EVT VT =
Op.getValueType();
11662 if (VT == MVT::v2f64 &&
C)
11665 if (Subtarget.hasP9Vector()) {
11674 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11680 BitcastLoad,
Op.getOperand(2));
11681 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11685 if (Subtarget.isISA3_1()) {
11686 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11690 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11691 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11701 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11704 unsigned InsertAtElement =
C->getZExtValue();
11705 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11707 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11721 EVT VT =
Op.getValueType();
11723 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11729 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11730 "Type unsupported without MMA");
11731 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11732 "Type unsupported without paired vector support");
11737 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
11739 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11749 std::reverse(Loads.
begin(), Loads.
end());
11750 std::reverse(LoadChains.
begin(), LoadChains.
end());
11768 EVT StoreVT =
Value.getValueType();
11770 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11776 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11777 "Type unsupported without MMA");
11778 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11779 "Type unsupported without paired vector support");
11782 unsigned NumVecs = 2;
11783 if (StoreVT == MVT::v512i1) {
11784 if (Subtarget.isISAFuture()) {
11785 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11787 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
11790 Value2 =
SDValue(ExtNode, 1);
11795 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
11796 unsigned VecNum = Subtarget.
isLittleEndian() ? NumVecs - 1 - Idx : Idx;
11798 if (Subtarget.isISAFuture()) {
11799 VecNum = Subtarget.
isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
11801 Idx > 1 ? Value2 :
Value,
11808 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11822 if (
Op.getValueType() == MVT::v4i32) {
11823 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
11832 LHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v8i16, LHS);
11833 RHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v8i16, RHS);
11834 RHSSwap = DAG.
getNode(ISD::BITCAST, dl, MVT::v8i16, RHSSwap);
11839 LHS, RHS, DAG, dl, MVT::v4i32);
11842 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11847 }
else if (
Op.getValueType() == MVT::v16i8) {
11848 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
11853 LHS, RHS, DAG, dl, MVT::v8i16);
11854 EvenParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, EvenParts);
11858 LHS, RHS, DAG, dl, MVT::v8i16);
11859 OddParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OddParts);
11866 for (
unsigned i = 0; i != 8; ++i) {
11867 if (isLittleEndian) {
11869 Ops[i*2+1] = 2*i+16;
11872 Ops[i*2+1] = 2*i+1+16;
11875 if (isLittleEndian)
11885 bool IsStrict =
Op->isStrictFPOpcode();
11886 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11887 !Subtarget.hasP9Vector())
11896 assert(
Op.getOpcode() == ISD::FP_EXTEND &&
11897 "Should only be called for ISD::FP_EXTEND");
11901 if (
Op.getValueType() != MVT::v2f64 ||
11902 Op.getOperand(0).getValueType() != MVT::v2f32)
11914 "Node should have 2 operands with second one being a constant!");
11926 int DWord = Idx >> 1;
11949 LD->getMemoryVT(),
LD->getMemOperand());
11962 LD->getMemoryVT(),
LD->getMemOperand());
11973 switch (
Op.getOpcode()) {
11975 case ISD::FPOW:
return lowerPow(
Op, DAG);
11976 case ISD::FSIN:
return lowerSin(
Op, DAG);
11977 case ISD::FCOS:
return lowerCos(
Op, DAG);
11978 case ISD::FLOG:
return lowerLog(
Op, DAG);
11979 case ISD::FLOG10:
return lowerLog10(
Op, DAG);
11980 case ISD::FEXP:
return lowerExp(
Op, DAG);
11989 case ISD::INIT_TRAMPOLINE:
return LowerINIT_TRAMPOLINE(
Op, DAG);
11990 case ISD::ADJUST_TRAMPOLINE:
return LowerADJUST_TRAMPOLINE(
Op, DAG);
11992 case ISD::INLINEASM:
11993 case ISD::INLINEASM_BR:
return LowerINLINEASM(
Op, DAG);
11995 case ISD::VASTART:
return LowerVASTART(
Op, DAG);
11996 case ISD::VAARG:
return LowerVAARG(
Op, DAG);
11997 case ISD::VACOPY:
return LowerVACOPY(
Op, DAG);
11999 case ISD::STACKRESTORE:
return LowerSTACKRESTORE(
Op, DAG);
12000 case ISD::DYNAMIC_STACKALLOC:
return LowerDYNAMIC_STACKALLOC(
Op, DAG);
12001 case ISD::GET_DYNAMIC_AREA_OFFSET:
12002 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12009 case ISD::LOAD:
return LowerLOAD(
Op, DAG);
12010 case ISD::STORE:
return LowerSTORE(
Op, DAG);
12022 case ISD::SET_ROUNDING:
12023 return LowerSET_ROUNDING(
Op, DAG);
12030 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12031 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12040 case ISD::FP_EXTEND:
return LowerFP_EXTEND(
Op, DAG);
12043 return LowerFP_ROUND(
Op, DAG);
12049 case ISD::BITCAST:
return LowerBITCAST(
Op, DAG);
12056 return LowerINTRINSIC_VOID(
Op, DAG);
12058 return LowerBSWAP(
Op, DAG);
12059 case ISD::ATOMIC_CMP_SWAP:
12060 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12061 case ISD::ATOMIC_STORE:
12062 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12064 return LowerIS_FPCLASS(
Op, DAG);
12072 switch (
N->getOpcode()) {
12074 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12075 case ISD::ATOMIC_LOAD: {
12081 case ISD::READCYCLECOUNTER: {
12091 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12094 assert(
N->getValueType(0) == MVT::i1 &&
12095 "Unexpected result type for CTR decrement intrinsic");
12097 N->getValueType(0));
12107 switch (
N->getConstantOperandVal(0)) {
12108 case Intrinsic::ppc_pack_longdouble:
12110 N->getOperand(2),
N->getOperand(1)));
12112 case Intrinsic::ppc_maxfe:
12113 case Intrinsic::ppc_minfe:
12114 case Intrinsic::ppc_fnmsub:
12115 case Intrinsic::ppc_convert_f128_to_ppcf128:
12125 EVT VT =
N->getValueType(0);
12127 if (VT == MVT::i64) {
12140 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12144 Results.push_back(LoweredValue);
12145 if (
N->isStrictFPOpcode())
12150 if (!
N->getValueType(0).isVector())
12170 case ISD::FP_EXTEND:
12183 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
12185 return Builder.CreateCall(Func, {});
12208 return Builder.CreateCall(
12210 Builder.GetInsertBlock()->getParent()->getParent(),
12211 Intrinsic::ppc_cfence, {Inst->getType()}),
12221 unsigned AtomicSize,
12222 unsigned BinOpcode,
12223 unsigned CmpOpcode,
12224 unsigned CmpPred)
const {
12228 auto LoadMnemonic = PPC::LDARX;
12229 auto StoreMnemonic = PPC::STDCX;
12230 switch (AtomicSize) {
12234 LoadMnemonic = PPC::LBARX;
12235 StoreMnemonic = PPC::STBCX;
12236 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12239 LoadMnemonic = PPC::LHARX;
12240 StoreMnemonic = PPC::STHCX;
12241 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12244 LoadMnemonic = PPC::LWARX;
12245 StoreMnemonic = PPC::STWCX;
12248 LoadMnemonic = PPC::LDARX;
12249 StoreMnemonic = PPC::STDCX;
12265 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12269 F->insert(It, loop2MBB);
12270 F->insert(It, exitMBB);
12276 Register TmpReg = (!BinOpcode) ? incr :
12277 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
12278 : &PPC::GPRCRegClass);
12303 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
12308 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
12310 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
12311 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
12312 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
12340 switch(
MI.getOpcode()) {
12344 return TII->isSignExtended(
MI.getOperand(1).getReg(),
12345 &
MI.getMF()->getRegInfo());
12369 case PPC::EXTSB8_32_64:
12370 case PPC::EXTSB8_rec:
12371 case PPC::EXTSB_rec:
12374 case PPC::EXTSH8_32_64:
12375 case PPC::EXTSH8_rec:
12376 case PPC::EXTSH_rec:
12378 case PPC::EXTSWSLI:
12379 case PPC::EXTSWSLI_32_64:
12380 case PPC::EXTSWSLI_32_64_rec:
12381 case PPC::EXTSWSLI_rec:
12382 case PPC::EXTSW_32:
12383 case PPC::EXTSW_32_64:
12384 case PPC::EXTSW_32_64_rec:
12385 case PPC::EXTSW_rec:
12388 case PPC::SRAWI_rec:
12389 case PPC::SRAW_rec:
12398 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12408 bool IsSignExtended =
12411 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12412 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
12413 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12414 .
addReg(
MI.getOperand(3).getReg());
12415 MI.getOperand(3).setReg(ValueReg);
12419 if (Subtarget.hasPartwordAtomics())
12427 bool is64bit = Subtarget.
isPPC64();
12429 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12440 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12444 F->insert(It, loop2MBB);
12445 F->insert(It, exitMBB);
12451 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12454 Register PtrReg = RegInfo.createVirtualRegister(RC);
12455 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
12457 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
12458 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
12459 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
12460 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
12461 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
12462 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
12463 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
12464 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
12465 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
12466 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
12469 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
12496 if (ptrA != ZeroReg) {
12497 Ptr1Reg = RegInfo.createVirtualRegister(RC);
12498 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12506 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12507 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12510 .
addImm(is8bit ? 28 : 27);
12511 if (!isLittleEndian)
12512 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12514 .
addImm(is8bit ? 24 : 16);
12516 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12521 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12531 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12535 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12540 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12544 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12547 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12554 Register SReg = RegInfo.createVirtualRegister(GPRC);
12555 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
12559 unsigned ValueReg = SReg;
12560 unsigned CmpReg = Incr2Reg;
12561 if (CmpOpcode == PPC::CMPW) {
12562 ValueReg = RegInfo.createVirtualRegister(GPRC);
12563 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12566 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
12567 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12569 ValueReg = ValueSReg;
12601 .
addImm(is8bit ? 24 : 16)
12622 Register DstReg =
MI.getOperand(0).getReg();
12624 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12625 Register mainDstReg =
MRI.createVirtualRegister(RC);
12626 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12629 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12630 "Invalid Pointer Size!");
12678 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12679 Register BufReg =
MI.getOperand(1).getReg();
12694 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12696 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12699 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12722 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12743 TII->get(PPC::PHI), DstReg)
12747 MI.eraseFromParent();
12761 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12762 "Invalid Pointer Size!");
12765 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12768 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12769 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12783 Register BufReg =
MI.getOperand(0).getReg();
12788 if (PVT == MVT::i64) {
12800 if (PVT == MVT::i64) {
12812 if (PVT == MVT::i64) {
12824 if (PVT == MVT::i64) {
12836 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12846 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12849 MI.eraseFromParent();
12865 "Unexpected stack alignment");
12869 unsigned StackProbeSize =
12872 StackProbeSize &= ~(StackAlign - 1);
12873 return StackProbeSize ? StackProbeSize : StackAlign;
12885 const bool isPPC64 = Subtarget.
isPPC64();
12917 MF->
insert(MBBIter, TestMBB);
12918 MF->
insert(MBBIter, BlockMBB);
12919 MF->
insert(MBBIter, TailMBB);
12924 Register DstReg =
MI.getOperand(0).getReg();
12925 Register NegSizeReg =
MI.getOperand(1).getReg();
12926 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12927 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12928 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12929 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12935 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12937 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12943 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12944 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12946 .
addDef(ActualNegSizeReg)
12948 .
add(
MI.getOperand(2))
12949 .
add(
MI.getOperand(3));
12955 .
addReg(ActualNegSizeReg);
12958 int64_t NegProbeSize = -(int64_t)ProbeSize;
12960 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12962 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12964 .
addImm(NegProbeSize >> 16);
12968 .
addImm(NegProbeSize & 0xFFFF);
12975 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12977 .
addReg(ActualNegSizeReg)
12979 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12983 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12986 .
addReg(ActualNegSizeReg);
12995 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12996 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13010 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
13021 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13023 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13024 MaxCallFrameSizeReg)
13025 .
add(
MI.getOperand(2))
13026 .
add(
MI.getOperand(3));
13027 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13029 .
addReg(MaxCallFrameSizeReg);
13038 MI.eraseFromParent();
13040 ++NumDynamicAllocaProbed;
13045 switch (
MI.getOpcode()) {
13046 case PPC::SELECT_CC_I4:
13047 case PPC::SELECT_CC_I8:
13048 case PPC::SELECT_CC_F4:
13049 case PPC::SELECT_CC_F8:
13050 case PPC::SELECT_CC_F16:
13051 case PPC::SELECT_CC_VRRC:
13052 case PPC::SELECT_CC_VSFRC:
13053 case PPC::SELECT_CC_VSSRC:
13054 case PPC::SELECT_CC_VSRC:
13055 case PPC::SELECT_CC_SPE4:
13056 case PPC::SELECT_CC_SPE:
13064 switch (
MI.getOpcode()) {
13065 case PPC::SELECT_I4:
13066 case PPC::SELECT_I8:
13067 case PPC::SELECT_F4:
13068 case PPC::SELECT_F8:
13069 case PPC::SELECT_F16:
13070 case PPC::SELECT_SPE:
13071 case PPC::SELECT_SPE4:
13072 case PPC::SELECT_VRRC:
13073 case PPC::SELECT_VSFRC:
13074 case PPC::SELECT_VSSRC:
13075 case PPC::SELECT_VSRC:
13085 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13086 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13088 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13101 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13102 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13104 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13105 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13119 if (Subtarget.hasISEL() &&
13120 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13121 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13122 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13124 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13125 MI.getOpcode() == PPC::SELECT_CC_I8)
13129 Cond.push_back(
MI.getOperand(1));
13132 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13133 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13149 F->insert(It, copy0MBB);
13150 F->insert(It, sinkMBB);
13154 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13169 .
addReg(
MI.getOperand(1).getReg())
13172 unsigned SelectPred =
MI.getOperand(4).getImm();
13175 .
addReg(
MI.getOperand(1).getReg())
13192 .
addReg(
MI.getOperand(3).getReg())
13194 .
addReg(
MI.getOperand(2).getReg())
13196 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13212 F->insert(It, readMBB);
13213 F->insert(It, sinkMBB);
13224 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13232 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13234 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13244 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13246 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13248 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13250 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13253 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13255 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13257 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13259 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13262 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13264 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13266 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13268 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13271 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13273 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13275 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
13277 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
13280 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
13282 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
13284 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
13286 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
13289 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
13291 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
13293 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
13295 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
13298 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
13300 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
13302 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
13304 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
13307 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
13309 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
13311 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
13313 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
13316 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
13318 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
13320 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
13322 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
13325 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
13327 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
13329 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
13331 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
13334 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
13336 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
13338 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
13340 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
13342 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
13343 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
13344 (Subtarget.hasPartwordAtomics() &&
13345 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
13346 (Subtarget.hasPartwordAtomics() &&
13347 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
13348 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
13350 auto LoadMnemonic = PPC::LDARX;
13351 auto StoreMnemonic = PPC::STDCX;
13352 switch (
MI.getOpcode()) {
13355 case PPC::ATOMIC_CMP_SWAP_I8:
13356 LoadMnemonic = PPC::LBARX;
13357 StoreMnemonic = PPC::STBCX;
13358 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13360 case PPC::ATOMIC_CMP_SWAP_I16:
13361 LoadMnemonic = PPC::LHARX;
13362 StoreMnemonic = PPC::STHCX;
13363 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13365 case PPC::ATOMIC_CMP_SWAP_I32:
13366 LoadMnemonic = PPC::LWARX;
13367 StoreMnemonic = PPC::STWCX;
13369 case PPC::ATOMIC_CMP_SWAP_I64:
13370 LoadMnemonic = PPC::LDARX;
13371 StoreMnemonic = PPC::STDCX;
13378 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13379 Register oldval =
MI.getOperand(3).getReg();
13380 Register newval =
MI.getOperand(4).getReg();
13387 F->insert(It, loop2MBB);
13388 F->insert(It, exitMBB);
13409 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13435 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13436 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13440 bool is64bit = Subtarget.
isPPC64();
13442 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13447 Register oldval =
MI.getOperand(3).getReg();
13448 Register newval =
MI.getOperand(4).getReg();
13455 F->insert(It, loop2MBB);
13456 F->insert(It, exitMBB);
13463 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13466 Register PtrReg = RegInfo.createVirtualRegister(RC);
13467 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13469 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13470 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
13471 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
13472 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
13473 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
13474 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13475 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13476 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13477 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13478 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13479 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13481 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
13482 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13483 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13514 if (ptrA != ZeroReg) {
13515 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13516 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13525 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13526 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13529 .
addImm(is8bit ? 28 : 27);
13530 if (!isLittleEndian)
13531 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13533 .
addImm(is8bit ? 24 : 16);
13535 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13540 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13545 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13548 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13555 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13559 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13562 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13565 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13570 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13587 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13611 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13621 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
13636 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13644 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13645 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13646 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13647 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13648 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13649 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13652 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13653 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13656 Register Dest = RegInfo.createVirtualRegister(
13657 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13661 .
addReg(
MI.getOperand(1).getReg())
13664 MI.getOperand(0).getReg())
13665 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13666 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13669 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13672 MI.getOperand(0).getReg())
13674 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13676 unsigned Imm =
MI.getOperand(1).getImm();
13679 MI.getOperand(0).getReg())
13681 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13683 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13686 if (
MRI.use_empty(OldFPSCRReg))
13687 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13689 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13700 unsigned Mode =
MI.getOperand(1).getImm();
13701 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13705 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13708 }
else if (
MI.getOpcode() == PPC::SETRND) {
13716 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13717 if (Subtarget.hasDirectMove()) {
13718 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13722 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13725 if (RC == &PPC::F8RCRegClass) {
13727 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
13728 "Unsupported RegClass.");
13730 StoreOp = PPC::STFD;
13734 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
13735 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13736 "Unsupported RegClass.");
13769 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13772 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13784 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
13786 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13788 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
13789 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
13794 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13795 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13800 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
13801 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13807 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
13808 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13817 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13821 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13822 if (
MRI.use_empty(OldFPSCRReg))
13823 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13825 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13828 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13834 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13835 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13837 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13844 .
addUse(Src, 0, PPC::sub_gp8_x1);
13847 .
addUse(Src, 0, PPC::sub_gp8_x0);
13848 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13849 MI.getOpcode() == PPC::STQX_PSEUDO) {
13855 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13861 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13862 :
TII->get(PPC::STQ))
13870 MI.eraseFromParent();
13883 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
13886 return RefinementSteps;
13892 EVT VT =
Op.getValueType();
13895 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
13919PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
13922 EVT VT =
Op.getValueType();
13923 if (VT != MVT::f64 &&
13924 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
13931 int Enabled,
int &RefinementSteps,
13932 bool &UseOneConstNR,
13933 bool Reciprocal)
const {
13935 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
13936 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
13937 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13938 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13944 UseOneConstNR = !Subtarget.needsTwoConstNR();
13952 int &RefinementSteps)
const {
13954 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
13955 (VT == MVT::f64 && Subtarget.hasFRE()) ||
13956 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13957 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13965unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13993 Base = Loc.getOperand(0);
14003 unsigned Bytes,
int Dist,
14017 if (FS != BFS || FS != (
int)Bytes)
return false;
14021 SDValue Base1 = Loc, Base2 = BaseLoc;
14022 int64_t Offset1 = 0, Offset2 = 0;
14025 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14035 if (isGA1 && isGA2 && GV1 == GV2)
14036 return Offset1 == (Offset2 + Dist*Bytes);
14043 unsigned Bytes,
int Dist,
14046 EVT VT = LS->getMemoryVT();
14047 SDValue Loc = LS->getBasePtr();
14053 switch (
N->getConstantOperandVal(1)) {
14054 default:
return false;
14055 case Intrinsic::ppc_altivec_lvx:
14056 case Intrinsic::ppc_altivec_lvxl:
14057 case Intrinsic::ppc_vsx_lxvw4x:
14058 case Intrinsic::ppc_vsx_lxvw4x_be:
14061 case Intrinsic::ppc_vsx_lxvd2x:
14062 case Intrinsic::ppc_vsx_lxvd2x_be:
14065 case Intrinsic::ppc_altivec_lvebx:
14068 case Intrinsic::ppc_altivec_lvehx:
14071 case Intrinsic::ppc_altivec_lvewx:
14081 switch (
N->getConstantOperandVal(1)) {
14082 default:
return false;
14083 case Intrinsic::ppc_altivec_stvx:
14084 case Intrinsic::ppc_altivec_stvxl:
14085 case Intrinsic::ppc_vsx_stxvw4x:
14088 case Intrinsic::ppc_vsx_stxvd2x:
14091 case Intrinsic::ppc_vsx_stxvw4x_be:
14094 case Intrinsic::ppc_vsx_stxvd2x_be:
14097 case Intrinsic::ppc_altivec_stvebx:
14100 case Intrinsic::ppc_altivec_stvehx:
14103 case Intrinsic::ppc_altivec_stvewx:
14120 SDValue Chain = LD->getChain();
14121 EVT VT = LD->getMemoryVT();
14130 while (!Queue.empty()) {
14131 SDNode *ChainNext = Queue.pop_back_val();
14132 if (!Visited.
insert(ChainNext).second)
14139 if (!Visited.
count(ChainLD->getChain().getNode()))
14140 Queue.push_back(ChainLD->getChain().getNode());
14142 for (
const SDUse &O : ChainNext->
ops())
14143 if (!Visited.
count(O.getNode()))
14144 Queue.push_back(O.getNode());
14146 LoadRoots.
insert(ChainNext);
14157 for (
SDNode *
I : LoadRoots) {
14158 Queue.push_back(
I);
14160 while (!Queue.empty()) {
14161 SDNode *LoadRoot = Queue.pop_back_val();
14162 if (!Visited.
insert(LoadRoot).second)
14174 Queue.push_back(U);
14207 auto Final = Shifted;
14218 DAGCombinerInfo &DCI)
const {
14226 if (!DCI.isAfterLegalizeDAG())
14236 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14240 if (OpSize <
Size) {
14258 DAGCombinerInfo &DCI)
const {
14262 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14273 N->getValueType(0) != MVT::i1)
14276 if (
N->getOperand(0).getValueType() != MVT::i32 &&
14277 N->getOperand(0).getValueType() != MVT::i64)
14287 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
14298 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
14321 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14322 N->getOperand(0).getOpcode() !=
ISD::OR &&
14323 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14333 N->getOperand(1).getOpcode() !=
ISD::AND &&
14334 N->getOperand(1).getOpcode() !=
ISD::OR &&
14335 N->getOperand(1).getOpcode() !=
ISD::XOR &&
14348 for (
unsigned i = 0; i < 2; ++i) {
14352 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
14364 while (!BinOps.
empty()) {
14372 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14406 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14430 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14452 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14461 std::list<HandleSDNode> PromOpHandles;
14462 for (
auto &PromOp : PromOps)
14463 PromOpHandles.emplace_back(PromOp);
14470 while (!PromOpHandles.empty()) {
14472 PromOpHandles.pop_back();
14481 PromOpHandles.emplace_front(PromOp);
14495 default:
C = 0;
break;
14508 PromOpHandles.emplace_front(PromOp);
14515 for (
unsigned i = 0; i < 2; ++i)
14525 return N->getOperand(0);
14533 DAGCombinerInfo &DCI)
const {
14551 if (
N->getValueType(0) != MVT::i32 &&
14552 N->getValueType(0) != MVT::i64)
14555 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14556 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14559 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14560 N->getOperand(0).getOpcode() !=
ISD::OR &&
14561 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14572 while (!BinOps.
empty()) {
14580 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14611 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14623 SelectTruncOp[0].
insert(std::make_pair(
User,
14627 SelectTruncOp[0].
insert(std::make_pair(
User,
14630 SelectTruncOp[1].
insert(std::make_pair(
User,
14636 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14645 SelectTruncOp[0].
insert(std::make_pair(
User,
14649 SelectTruncOp[0].
insert(std::make_pair(
User,
14652 SelectTruncOp[1].
insert(std::make_pair(
User,
14658 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14659 bool ReallyNeedsExt =
false;
14663 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14668 Inputs[i].getOperand(0).getValueSizeInBits();
14669 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14674 OpBits-PromBits))) ||
14677 (OpBits-(PromBits-1)))) {
14678 ReallyNeedsExt =
true;
14686 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14693 SDValue InSrc = Inputs[i].getOperand(0);
14707 std::list<HandleSDNode> PromOpHandles;
14708 for (
auto &PromOp : PromOps)
14709 PromOpHandles.emplace_back(PromOp);
14715 while (!PromOpHandles.empty()) {
14717 PromOpHandles.pop_back();
14721 default:
C = 0;
break;
14734 PromOpHandles.emplace_front(PromOp);
14744 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14746 PromOpHandles.emplace_front(PromOp);
14755 for (
unsigned i = 0; i < 2; ++i) {
14773 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14774 if (SI0 != SelectTruncOp[0].end())
14776 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14777 if (SI1 != SelectTruncOp[1].end())
14786 if (!ReallyNeedsExt)
14787 return N->getOperand(0);
14794 N->getValueSizeInBits(0), PromBits),
14795 dl,
N->getValueType(0)));
14798 "Invalid extension type");
14801 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14809 DAGCombinerInfo &DCI)
const {
14811 "Should be called with a SETCC node");
14829 EVT VT =
N->getValueType(0);
14830 EVT OpVT = LHS.getValueType();
14836 return DAGCombineTruncBoolExt(
N, DCI);
14843 Op.getValueType() == MVT::f64;
14855combineElementTruncationToVectorTruncation(
SDNode *
N,
14856 DAGCombinerInfo &DCI)
const {
14858 "Should be called with a BUILD_VECTOR node");
14865 "The input operand must be an fp-to-int conversion.");
14874 bool IsSplat =
true;
14879 EVT TargetVT =
N->getValueType(0);
14880 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14885 if (NextConversion != FirstConversion)
14893 if (
N->getOperand(i) != FirstInput)
14904 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14905 SDValue In =
N->getOperand(i).getOperand(0);
14928 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
14930 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14943 "Should be called with a BUILD_VECTOR node");
14948 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14951 bool InputsAreConsecutiveLoads =
true;
14952 bool InputsAreReverseConsecutive =
true;
14953 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14955 bool IsRoundOfExtLoad =
false;
14964 if ((!IsRoundOfExtLoad && FirstInput.
getOpcode() != ISD::LOAD) ||
14965 N->getNumOperands() == 1)
14968 if (!IsRoundOfExtLoad)
14973 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
14975 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14978 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14980 if (NextInput.
getOpcode() != ISD::LOAD)
14984 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14995 InputsAreConsecutiveLoads =
false;
14997 InputsAreReverseConsecutive =
false;
15000 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
15005 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
15006 "The loads cannot be both consecutive and reverse consecutive.");
15010 if (InputsAreConsecutiveLoads) {
15011 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
15015 ReturnSDVal = WideLoad;
15016 }
else if (InputsAreReverseConsecutive) {
15018 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
15023 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
15027 DAG.
getUNDEF(
N->getValueType(0)), Ops);
15031 for (
auto *LD : InputLoads)
15033 return ReturnSDVal;
15044 unsigned NumElems = Input.getValueType().getVectorNumElements();
15050 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15052 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
15054 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
15055 CorrectElems = CorrectElems >> 8;
15056 Elems = Elems >> 8;
15061 DAG.
getUNDEF(Input.getValueType()), ShuffleMask);
15063 EVT VT =
N->getValueType(0);
15067 Input.getValueType().getVectorElementType(),
15101 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
15121 if (Input && Input != Extract.
getOperand(0))
15127 Elems = Elems << 8;
15136 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15137 if (!isSExtOfVecExtract(
N->getOperand(i))) {
15144 int TgtElemArrayIdx;
15146 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
15147 if (InputSize + OutputSize == 40)
15148 TgtElemArrayIdx = 0;
15149 else if (InputSize + OutputSize == 72)
15150 TgtElemArrayIdx = 1;
15151 else if (InputSize + OutputSize == 48)
15152 TgtElemArrayIdx = 2;
15153 else if (InputSize + OutputSize == 80)
15154 TgtElemArrayIdx = 3;
15155 else if (InputSize + OutputSize == 96)
15156 TgtElemArrayIdx = 4;
15160 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
15162 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
15163 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
15164 if (Elems != CorrectElems) {
15180 if (
N->getValueType(0) != MVT::v1i128)
15190 EVT MemoryType = LD->getMemoryVT();
15194 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
15195 MemoryType == MVT::i32 || MemoryType == MVT::i64;
15198 if (!ValidLDType ||
15204 LD->getChain(), LD->getBasePtr(),
15208 DAG.
getVTList(MVT::v1i128, MVT::Other),
15209 LoadOps, MemoryType, LD->getMemOperand());
15213 DAGCombinerInfo &DCI)
const {
15215 "Should be called with a BUILD_VECTOR node");
15220 if (!Subtarget.hasVSX())
15228 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
15243 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15252 if (Subtarget.isISA3_1()) {
15258 if (
N->getValueType(0) != MVT::v2f64)
15269 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
15280 if (!Ext1Op || !Ext2Op)
15289 if (FirstElem == 0 && SecondElem == 1)
15291 else if (FirstElem == 2 && SecondElem == 3)
15299 return DAG.
getNode(NodeType, dl, MVT::v2f64,
15304 DAGCombinerInfo &DCI)
const {
15307 "Need an int -> FP conversion node here");
15318 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
15320 if (!
Op.getOperand(0).getValueType().isSimple())
15322 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
15323 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
15326 SDValue FirstOperand(
Op.getOperand(0));
15327 bool SubWordLoad = FirstOperand.getOpcode() == ISD::LOAD &&
15328 (FirstOperand.getValueType() == MVT::i8 ||
15329 FirstOperand.getValueType() == MVT::i16);
15330 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
15332 bool DstDouble =
Op.getValueType() == MVT::f64;
15333 unsigned ConvOp =
Signed ?
15340 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
15343 Ops, MVT::i8, LDN->getMemOperand());
15348 SDValue ExtOps[] = { Ld, WidthConst };
15350 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
15352 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
15360 if (
Op.getOperand(0).getValueType() == MVT::i32)
15364 "UINT_TO_FP is supported only with FPCVT");
15368 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15373 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15380 Subtarget.hasFPCVT()) ||
15382 SDValue Src =
Op.getOperand(0).getOperand(0);
15383 if (Src.getValueType() == MVT::f32) {
15384 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
15385 DCI.AddToWorklist(Src.getNode());
15386 }
else if (Src.getValueType() != MVT::f64) {
15398 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15401 DCI.AddToWorklist(
FP.getNode());
15425 switch (
N->getOpcode()) {
15430 Chain = LD->getChain();
15431 Base = LD->getBasePtr();
15432 MMO = LD->getMemOperand();
15451 MVT VecTy =
N->getValueType(0).getSimpleVT();
15459 Chain = Load.getValue(1);
15465 if (VecTy != MVT::v2f64) {
15492 switch (
N->getOpcode()) {
15497 Chain = ST->getChain();
15498 Base = ST->getBasePtr();
15499 MMO = ST->getMemOperand();
15519 SDValue Src =
N->getOperand(SrcOpnd);
15520 MVT VecTy = Src.getValueType().getSimpleVT();
15523 if (VecTy != MVT::v2f64) {
15524 Src = DAG.
getNode(ISD::BITCAST, dl, MVT::v2f64, Src);
15529 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15535 StoreOps, VecTy, MMO);
15542 DAGCombinerInfo &DCI)
const {
15545 unsigned Opcode =
N->getOperand(1).getOpcode();
15547 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15551 &&
"Not a FP_TO_INT Instruction!");
15554 EVT Op1VT =
N->getOperand(1).getValueType();
15557 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15561 bool ValidTypeForStoreFltAsInt =
15562 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15563 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15566 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15569 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15592 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15593 for (
int i = 1, e = Mask.size(); i < e; i++) {
15594 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15596 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15598 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15610 FirstOp =
Op.getOperand(i);
15617 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15625 if (
Op.getOpcode() != ISD::BITCAST)
15627 Op =
Op.getOperand(0);
15642 int LHSMaxIdx,
int RHSMinIdx,
15643 int RHSMaxIdx,
int HalfVec,
15644 unsigned ValidLaneWidth,
15646 for (
int i = 0, e = ShuffV.
size(); i < e; i++) {
15647 int Idx = ShuffV[i];
15648 if ((Idx >= 0 && Idx < LHSMaxIdx) || (Idx >= RHSMinIdx && Idx < RHSMaxIdx))
15650 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
15661 SDLoc dl(OrigSToV);
15664 "Expecting a SCALAR_TO_VECTOR here");
15677 "Cannot produce a permuted scalar_to_vector for one element vector");
15679 unsigned ResultInElt = NumElts / 2;
15706 int NumElts = LHS.getValueType().getVectorNumElements();
15716 if (!Subtarget.hasDirectMove())
15735 if (SToVLHS || SToVRHS) {
15742 if (SToVLHS && SToVRHS &&
15749 int NumEltsOut = ShuffV.
size();
15754 unsigned ValidLaneWidth =
15756 LHS.getValueType().getScalarSizeInBits()
15758 RHS.getValueType().getScalarSizeInBits();
15762 int LHSMaxIdx = -1;
15763 int RHSMinIdx = -1;
15764 int RHSMaxIdx = -1;
15765 int HalfVec = LHS.getValueType().getVectorNumElements() / 2;
15777 LHSMaxIdx = NumEltsOut / NumEltsIn;
15780 SToVLHS = DAG.
getBitcast(LHS.getValueType(), SToVLHS);
15786 RHSMinIdx = NumEltsOut;
15787 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
15790 SToVRHS = DAG.
getBitcast(RHS.getValueType(), SToVRHS);
15800 HalfVec, ValidLaneWidth, Subtarget);
15826 if (IsLittleEndian) {
15829 if (Mask[0] < NumElts)
15830 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15834 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
15839 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
15843 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
15848 if (Mask[0] < NumElts)
15849 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
15853 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
15858 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15862 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
15872 if (IsLittleEndian)
15881 DAGCombinerInfo &DCI)
const {
15883 "Not a reverse memop pattern!");
15888 auto I =
Mask.rbegin();
15889 auto E =
Mask.rend();
15891 for (;
I !=
E; ++
I) {
15908 if (!Subtarget.hasP9Vector())
15911 if(!IsElementReverse(SVN))
15914 if (LSBase->
getOpcode() == ISD::LOAD) {
15930 if (LSBase->
getOpcode() == ISD::STORE) {
15950 if (IntrinsicID == Intrinsic::ppc_stdcx)
15952 else if (IntrinsicID == Intrinsic::ppc_stwcx)
15954 else if (IntrinsicID == Intrinsic::ppc_sthcx)
15956 else if (IntrinsicID == Intrinsic::ppc_stbcx)
15967 switch (
N->getOpcode()) {
15970 return combineADD(
N, DCI);
15996 return combineSHL(
N, DCI);
15998 return combineSRA(
N, DCI);
16000 return combineSRL(
N, DCI);
16002 return combineMUL(
N, DCI);
16005 return combineFMALike(
N, DCI);
16008 return N->getOperand(0);
16012 return N->getOperand(0);
16018 return N->getOperand(0);
16024 return DAGCombineExtBoolTrunc(
N, DCI);
16026 return combineTRUNCATE(
N, DCI);
16028 if (
SDValue CSCC = combineSetCC(
N, DCI))
16032 return DAGCombineTruncBoolExt(
N, DCI);
16035 return combineFPToIntToFP(
N, DCI);
16044 EVT Op1VT =
N->getOperand(1).getValueType();
16045 unsigned Opcode =
N->getOperand(1).getOpcode();
16049 SDValue Val = combineStoreFPToInt(
N, DCI);
16063 N->getOperand(1).getNode()->hasOneUse() &&
16064 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
16065 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
16080 if (Op1VT.
bitsGT(mVT)) {
16085 if (Op1VT == MVT::i64)
16122 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
16123 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
16130 EVT VT = LD->getValueType(0);
16137 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
16138 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
16149 auto ReplaceTwoFloatLoad = [&]() {
16150 if (VT != MVT::i64)
16165 if (!LD->hasNUsesOfValue(2, 0))
16168 auto UI = LD->use_begin();
16169 while (UI.getUse().getResNo() != 0) ++UI;
16171 while (UI.getUse().getResNo() != 0) ++UI;
16172 SDNode *RightShift = *UI;
16180 if (RightShift->getOpcode() !=
ISD::SRL ||
16182 RightShift->getConstantOperandVal(1) != 32 ||
16183 !RightShift->hasOneUse())
16186 SDNode *Trunc2 = *RightShift->use_begin();
16195 if (Bitcast->getOpcode() != ISD::BITCAST ||
16196 Bitcast->getValueType(0) != MVT::f32)
16198 if (Bitcast2->
getOpcode() != ISD::BITCAST ||
16208 SDValue BasePtr = LD->getBasePtr();
16209 if (LD->isIndexed()) {
16211 "Non-pre-inc AM on PPC?");
16219 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
16220 LD->getPointerInfo(), LD->getAlign(),
16221 MMOFlags, LD->getAAInfo());
16227 LD->getPointerInfo().getWithOffset(4),
16230 if (LD->isIndexed()) {
16244 if (ReplaceTwoFloatLoad())
16247 EVT MemVT = LD->getMemoryVT();
16250 if (LD->isUnindexed() && VT.
isVector() &&
16253 !Subtarget.hasP8Vector() &&
16254 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
16255 VT == MVT::v4f32))) &&
16256 LD->getAlign() < ABIAlignment) {
16258 SDValue Chain = LD->getChain();
16287 MVT PermCntlTy, PermTy, LDTy;
16288 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
16289 : Intrinsic::ppc_altivec_lvsl;
16290 IntrLD = Intrinsic::ppc_altivec_lvx;
16291 IntrPerm = Intrinsic::ppc_altivec_vperm;
16292 PermCntlTy = MVT::v16i8;
16293 PermTy = MVT::v4i32;
16312 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
16316 BaseLoadOps, LDTy, BaseMMO);
16325 int IncValue = IncOffset;
16342 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
16346 ExtraLoadOps, LDTy, ExtraMMO);
16357 if (isLittleEndian)
16359 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
16362 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
16365 Perm = Subtarget.hasAltivec()
16366 ? DAG.
getNode(ISD::BITCAST, dl, VT, Perm)
16381 unsigned IID =
N->getConstantOperandVal(0);
16383 : Intrinsic::ppc_altivec_lvsl);
16384 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
16391 .
zext(
Add.getScalarValueSizeInBits()))) {
16392 SDNode *BasePtr =
Add->getOperand(0).getNode();
16393 for (
SDNode *U : BasePtr->uses()) {
16395 U->getConstantOperandVal(0) == IID) {
16406 SDNode *BasePtr =
Add->getOperand(0).getNode();
16407 for (
SDNode *U : BasePtr->uses()) {
16410 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16416 V->getConstantOperandVal(0) == IID) {
16428 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16429 IID == Intrinsic::ppc_altivec_vmaxsh ||
16430 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16446 V2.getOperand(1) == V1) {
16461 switch (
N->getConstantOperandVal(1)) {
16464 case Intrinsic::ppc_altivec_vsum4sbs:
16465 case Intrinsic::ppc_altivec_vsum4shs:
16466 case Intrinsic::ppc_altivec_vsum4ubs: {
16473 APInt APSplatBits, APSplatUndef;
16474 unsigned SplatBitSize;
16477 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16480 if (BVNIsConstantSplat && APSplatBits == 0)
16485 case Intrinsic::ppc_vsx_lxvw4x:
16486 case Intrinsic::ppc_vsx_lxvd2x:
16498 switch (
N->getConstantOperandVal(1)) {
16501 case Intrinsic::ppc_vsx_stxvw4x:
16502 case Intrinsic::ppc_vsx_stxvd2x:
16511 bool Is64BitBswapOn64BitTgt =
16512 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16514 N->getOperand(0).hasOneUse();
16515 if (IsSingleUseNormalLd &&
16516 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16517 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16528 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16529 MVT::i64 : MVT::i32, MVT::Other),
16530 Ops, LD->getMemoryVT(), LD->getMemOperand());
16534 if (
N->getValueType(0) == MVT::i16)
16551 !IsSingleUseNormalLd)
16556 if (!LD->isSimple())
16558 SDValue BasePtr = LD->getBasePtr();
16560 LD->getPointerInfo(), LD->getAlign());
16565 LD->getMemOperand(), 4, 4);
16575 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16584 if (!
N->getOperand(0).hasOneUse() &&
16585 !
N->getOperand(1).hasOneUse() &&
16586 !
N->getOperand(2).hasOneUse()) {
16589 SDNode *VCMPrecNode =
nullptr;
16595 UI->getOperand(1) ==
N->getOperand(1) &&
16596 UI->getOperand(2) ==
N->getOperand(2) &&
16597 UI->getOperand(0) ==
N->getOperand(0)) {
16610 SDNode *FlagUser =
nullptr;
16612 FlagUser ==
nullptr; ++UI) {
16613 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16626 return SDValue(VCMPrecNode, 0);
16648 auto RHSAPInt = RHS->getAsAPIntVal();
16649 if (!RHSAPInt.isIntN(64))
16652 unsigned Val = RHSAPInt.getZExtValue();
16653 auto isImpossibleCompare = [&]() {
16656 if (Val != 0 && Val != 1) {
16658 return N->getOperand(0);
16660 return DAG.
getNode(ISD::BR, dl, MVT::Other,
16661 N->getOperand(0),
N->getOperand(4));
16666 unsigned StoreWidth = 0;
16669 if (
SDValue Impossible = isImpossibleCompare())
16681 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
16686 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16687 MemNode->getMemoryVT(), MemNode->getMemOperand());
16691 if (
N->getOperand(0) == LHS.getValue(1))
16710 assert(isDot &&
"Can't compare against a vector result!");
16712 if (
SDValue Impossible = isImpossibleCompare())
16715 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16722 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
16727 switch (LHS.getConstantOperandVal(1)) {
16751 return DAGCombineBuildVector(
N, DCI);
16762 EVT VT =
N->getValueType(0);
16763 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16765 if ((VT != MVT::i32 && VT != MVT::i64) ||
16773 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16793 const APInt &DemandedElts,
16795 unsigned Depth)
const {
16797 switch (
Op.getOpcode()) {
16802 Known.
Zero = 0xFFFF0000;
16806 switch (
Op.getConstantOperandVal(0)) {
16808 case Intrinsic::ppc_altivec_vcmpbfp_p:
16809 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16810 case Intrinsic::ppc_altivec_vcmpequb_p:
16811 case Intrinsic::ppc_altivec_vcmpequh_p:
16812 case Intrinsic::ppc_altivec_vcmpequw_p:
16813 case Intrinsic::ppc_altivec_vcmpequd_p:
16814 case Intrinsic::ppc_altivec_vcmpequq_p:
16815 case Intrinsic::ppc_altivec_vcmpgefp_p:
16816 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16817 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16818 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16819 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16820 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16821 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16822 case Intrinsic::ppc_altivec_vcmpgtub_p:
16823 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16824 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16825 case Intrinsic::ppc_altivec_vcmpgtud_p:
16826 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16833 switch (
Op.getConstantOperandVal(1)) {
16836 case Intrinsic::ppc_load2r:
16838 Known.
Zero = 0xFFFF0000;
16869 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
16878 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
16880 LoopSize +=
TII->getInstSizeInBytes(J);
16885 if (LoopSize > 16 && LoopSize <= 32)
16899 if (Constraint.
size() == 1) {
16900 switch (Constraint[0]) {
16918 }
else if (Constraint ==
"wc") {
16920 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
16921 Constraint ==
"wf" || Constraint ==
"ws" ||
16922 Constraint ==
"wi" || Constraint ==
"ww") {
16935 Value *CallOperandVal =
info.CallOperandVal;
16938 if (!CallOperandVal)
16943 if (
StringRef(constraint) ==
"wc" && type->isIntegerTy(1))
16945 else if ((
StringRef(constraint) ==
"wa" ||
16948 type->isVectorTy())
16950 else if (
StringRef(constraint) ==
"wi" && type->isIntegerTy(64))
16952 else if (
StringRef(constraint) ==
"ws" && type->isDoubleTy())
16954 else if (
StringRef(constraint) ==
"ww" && type->isFloatTy())
16957 switch (*constraint) {
16962 if (type->isIntegerTy())
16966 if (type->isFloatTy())
16970 if (type->isDoubleTy())
16974 if (type->isVectorTy())
16987std::pair<unsigned, const TargetRegisterClass *>
16991 if (Constraint.
size() == 1) {
16993 switch (Constraint[0]) {
16995 if (VT == MVT::i64 && Subtarget.
isPPC64())
16996 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
16997 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
16999 if (VT == MVT::i64 && Subtarget.
isPPC64())
17000 return std::make_pair(0U, &PPC::G8RCRegClass);
17001 return std::make_pair(0U, &PPC::GPRCRegClass);
17007 if (Subtarget.hasSPE()) {
17008 if (VT == MVT::f32 || VT == MVT::i32)
17009 return std::make_pair(0U, &PPC::GPRCRegClass);
17010 if (VT == MVT::f64 || VT == MVT::i64)
17011 return std::make_pair(0U, &PPC::SPERCRegClass);
17013 if (VT == MVT::f32 || VT == MVT::i32)
17014 return std::make_pair(0U, &PPC::F4RCRegClass);
17015 if (VT == MVT::f64 || VT == MVT::i64)
17016 return std::make_pair(0U, &PPC::F8RCRegClass);
17020 if (Subtarget.hasAltivec() && VT.
isVector())
17021 return std::make_pair(0U, &PPC::VRRCRegClass);
17022 else if (Subtarget.hasVSX())
17024 return std::make_pair(0U, &PPC::VFRCRegClass);
17027 return std::make_pair(0U, &PPC::CRRCRegClass);
17029 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
17031 return std::make_pair(0U, &PPC::CRBITRCRegClass);
17032 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
17033 Constraint ==
"wf" || Constraint ==
"wi") &&
17034 Subtarget.hasVSX()) {
17038 return std::make_pair(0U, &PPC::VSRCRegClass);
17039 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17040 return std::make_pair(0U, &PPC::VSSRCRegClass);
17041 return std::make_pair(0U, &PPC::VSFRCRegClass);
17042 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
17043 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17044 return std::make_pair(0U, &PPC::VSSRCRegClass);
17046 return std::make_pair(0U, &PPC::VSFRCRegClass);
17047 }
else if (Constraint ==
"lr") {
17048 if (VT == MVT::i64)
17049 return std::make_pair(0U, &PPC::LR8RCRegClass);
17051 return std::make_pair(0U, &PPC::LRRCRegClass);
17056 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
17060 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
17061 int VSNum = atoi(Constraint.
data() + 3);
17062 assert(VSNum >= 0 && VSNum <= 63 &&
17063 "Attempted to access a vsr out of range");
17065 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
17066 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
17071 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
17072 int RegNum = atoi(Constraint.
data() + 2);
17073 if (RegNum > 31 || RegNum < 0)
17075 if (VT == MVT::f32 || VT == MVT::i32)
17076 return Subtarget.hasSPE()
17077 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
17078 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
17079 if (VT == MVT::f64 || VT == MVT::i64)
17080 return Subtarget.hasSPE()
17081 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
17082 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
17086 std::pair<unsigned, const TargetRegisterClass *> R =
17095 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
17096 PPC::GPRCRegClass.contains(R.first))
17097 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
17098 PPC::sub_32, &PPC::G8RCRegClass),
17099 &PPC::G8RCRegClass);
17102 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
17103 R.first = PPC::CR0;
17104 R.second = &PPC::CRRCRegClass;
17108 if (Subtarget.
isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
17109 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
17110 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
17111 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
17112 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
17113 "default AIX AltiVec ABI and cannot be used\n";
17123 std::vector<SDValue> &Ops,
17128 if (Constraint.
size() > 1)
17131 char Letter = Constraint[0];
17146 EVT TCVT = MVT::i64;
17187 if (Result.getNode()) {
17188 Ops.push_back(Result);
17199 if (
I.getNumOperands() <= 1)
17203 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
17204 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
17205 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
17208 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
17224 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
17236 switch (AM.
Scale) {
17267 unsigned Depth =
Op.getConstantOperandVal(0);
17273 bool isPPC64 = Subtarget.
isPPC64();
17285 isPPC64 ? MVT::i64 : MVT::i32);
17292 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
17300 unsigned Depth =
Op.getConstantOperandVal(0);
17307 bool isPPC64 = PtrVT == MVT::i64;
17313 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
17315 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
17329 bool isPPC64 = Subtarget.
isPPC64();
17381 unsigned Intrinsic)
const {
17382 switch (Intrinsic) {
17383 case Intrinsic::ppc_atomicrmw_xchg_i128:
17384 case Intrinsic::ppc_atomicrmw_add_i128:
17385 case Intrinsic::ppc_atomicrmw_sub_i128:
17386 case Intrinsic::ppc_atomicrmw_nand_i128:
17387 case Intrinsic::ppc_atomicrmw_and_i128:
17388 case Intrinsic::ppc_atomicrmw_or_i128:
17389 case Intrinsic::ppc_atomicrmw_xor_i128:
17390 case Intrinsic::ppc_cmpxchg_i128:
17392 Info.memVT = MVT::i128;
17393 Info.ptrVal =
I.getArgOperand(0);
17395 Info.align =
Align(16);
17399 case Intrinsic::ppc_atomic_load_i128:
17401 Info.memVT = MVT::i128;
17402 Info.ptrVal =
I.getArgOperand(0);
17404 Info.align =
Align(16);
17407 case Intrinsic::ppc_atomic_store_i128:
17409 Info.memVT = MVT::i128;
17410 Info.ptrVal =
I.getArgOperand(2);
17412 Info.align =
Align(16);
17415 case Intrinsic::ppc_altivec_lvx:
17416 case Intrinsic::ppc_altivec_lvxl:
17417 case Intrinsic::ppc_altivec_lvebx:
17418 case Intrinsic::ppc_altivec_lvehx:
17419 case Intrinsic::ppc_altivec_lvewx:
17420 case Intrinsic::ppc_vsx_lxvd2x:
17421 case Intrinsic::ppc_vsx_lxvw4x:
17422 case Intrinsic::ppc_vsx_lxvd2x_be:
17423 case Intrinsic::ppc_vsx_lxvw4x_be:
17424 case Intrinsic::ppc_vsx_lxvl:
17425 case Intrinsic::ppc_vsx_lxvll: {
17427 switch (Intrinsic) {
17428 case Intrinsic::ppc_altivec_lvebx:
17431 case Intrinsic::ppc_altivec_lvehx:
17434 case Intrinsic::ppc_altivec_lvewx:
17437 case Intrinsic::ppc_vsx_lxvd2x:
17438 case Intrinsic::ppc_vsx_lxvd2x_be:
17448 Info.ptrVal =
I.getArgOperand(0);
17451 Info.align =
Align(1);
17455 case Intrinsic::ppc_altivec_stvx:
17456 case Intrinsic::ppc_altivec_stvxl:
17457 case Intrinsic::ppc_altivec_stvebx:
17458 case Intrinsic::ppc_altivec_stvehx:
17459 case Intrinsic::ppc_altivec_stvewx:
17460 case Intrinsic::ppc_vsx_stxvd2x:
17461 case Intrinsic::ppc_vsx_stxvw4x:
17462 case Intrinsic::ppc_vsx_stxvd2x_be:
17463 case Intrinsic::ppc_vsx_stxvw4x_be:
17464 case Intrinsic::ppc_vsx_stxvl:
17465 case Intrinsic::ppc_vsx_stxvll: {
17467 switch (Intrinsic) {
17468 case Intrinsic::ppc_altivec_stvebx:
17471 case Intrinsic::ppc_altivec_stvehx:
17474 case Intrinsic::ppc_altivec_stvewx:
17477 case Intrinsic::ppc_vsx_stxvd2x:
17478 case Intrinsic::ppc_vsx_stxvd2x_be:
17488 Info.ptrVal =
I.getArgOperand(1);
17491 Info.align =
Align(1);
17495 case Intrinsic::ppc_stdcx:
17496 case Intrinsic::ppc_stwcx:
17497 case Intrinsic::ppc_sthcx:
17498 case Intrinsic::ppc_stbcx: {
17500 auto Alignment =
Align(8);
17501 switch (Intrinsic) {
17502 case Intrinsic::ppc_stdcx:
17505 case Intrinsic::ppc_stwcx:
17507 Alignment =
Align(4);
17509 case Intrinsic::ppc_sthcx:
17511 Alignment =
Align(2);
17513 case Intrinsic::ppc_stbcx:
17515 Alignment =
Align(1);
17520 Info.ptrVal =
I.getArgOperand(0);
17522 Info.align = Alignment;
17540 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17541 if (
Op.isMemset() && Subtarget.hasVSX()) {
17546 if (TailSize > 2 && TailSize <= 4) {
17551 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17567 assert(Ty->isIntegerTy());
17569 unsigned BitSize = Ty->getPrimitiveSizeInBits();
17570 return !(BitSize == 0 || BitSize > 64);
17578 return NumBits1 == 64 && NumBits2 == 32;
17586 return NumBits1 == 64 && NumBits2 == 32;
17593 EVT MemVT = LD->getMemoryVT();
17594 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17595 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17611 "invalid fpext types");
17613 if (DestVT == MVT::f128)
17628 unsigned *
Fast)
const {
17642 !Subtarget.allowsUnalignedFPAccess())
17646 if (Subtarget.hasVSX()) {
17647 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17648 VT != MVT::v4f32 && VT != MVT::v4i32)
17655 if (VT == MVT::ppcf128)
17670 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17678 int64_t Imm = ConstNode->getSExtValue();
17701 switch (Ty->getScalarType()->getTypeID()) {
17706 return Subtarget.hasP9Vector();
17714 if (!
I->hasOneUse())
17718 assert(
User &&
"A single use instruction with no uses.");
17720 switch (
I->getOpcode()) {
17721 case Instruction::FMul: {
17723 if (
User->getOpcode() != Instruction::FSub &&
17724 User->getOpcode() != Instruction::FAdd)
17737 case Instruction::Load: {
17750 if (
User->getOpcode() != Instruction::Store)
17770 static const MCPhysReg ScratchRegs[] = {
17771 PPC::X12, PPC::LR8, PPC::CTR8, 0
17774 return ScratchRegs;
17778 const Constant *PersonalityFn)
const {
17779 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17783 const Constant *PersonalityFn)
const {
17784 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17789 EVT VT ,
unsigned DefinedValues)
const {
17790 if (VT == MVT::v2i64)
17791 return Subtarget.hasDirectMove();
17793 if (Subtarget.hasVSX())
17827 bool LegalOps,
bool OptForSize,
17829 unsigned Depth)
const {
17833 unsigned Opc =
Op.getOpcode();
17834 EVT VT =
Op.getValueType();
17859 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
17863 N0Cost,
Depth + 1);
17867 N1Cost,
Depth + 1);
17869 if (NegN0 && N0Cost <= N1Cost) {
17870 Cost = std::min(N0Cost, N2Cost);
17871 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
17872 }
else if (NegN1) {
17873 Cost = std::min(N1Cost, N2Cost);
17874 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
17917 bool ForCodeSize)
const {
17918 if (!VT.
isSimple() || !Subtarget.hasVSX())
17928 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
17933 APSInt IntResult(16,
false);
17938 if (IsExact && IntResult <= 15 && IntResult >= -16)
17940 return Imm.isZero();
17943 return Imm.isPosZero();
17955 unsigned Opcode =
N->getOpcode();
17956 unsigned TargetOpcode;
17975 if (Mask->getZExtValue() == OpSizeInBits - 1)
17981SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17987 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
17990 N->getValueType(0) != MVT::i64)
18005 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
18011SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18018SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18037 auto isZextOfCompareWithConstant = [](
SDValue Op) {
18039 Op.getValueType() != MVT::i64)
18043 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
18044 Cmp.getOperand(0).getValueType() != MVT::i64)
18048 int64_t NegConstant = 0 -
Constant->getSExtValue();
18057 bool LHSHasPattern = isZextOfCompareWithConstant(LHS);
18058 bool RHSHasPattern = isZextOfCompareWithConstant(RHS);
18061 if (LHSHasPattern && !RHSHasPattern)
18063 else if (!LHSHasPattern && !RHSHasPattern)
18068 SDValue Cmp = RHS.getOperand(0);
18069 SDValue Z = Cmp.getOperand(0);
18071 int64_t NegConstant = 0 -
Constant->getSExtValue();
18084 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18099 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18136 if (!GSDN || !ConstNode)
18156SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18176 DAGCombinerInfo &DCI)
const {
18178 if (Subtarget.useCRBits()) {
18180 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
18181 return CRTruncValue;
18188 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
18191 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
18201 EltToExtract = EltToExtract ? 0 : 1;
18211 return DCI.DAG.getNode(
18213 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
18218SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18222 if (!ConstOpOrElement)
18230 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
18254 return IsAddOne && IsNeg ? VT.
isVector() :
true;
18258 EVT VT =
N->getValueType(0);
18265 if ((MulAmtAbs - 1).isPowerOf2()) {
18269 if (!IsProfitable(IsNeg,
true, VT))
18282 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
18286 if (!IsProfitable(IsNeg,
false, VT))
18307 DAGCombinerInfo &DCI)
const {
18312 EVT VT =
N->getValueType(0);
18315 unsigned Opc =
N->getOpcode();
18317 bool LegalOps = !DCI.isBeforeLegalizeOps();
18325 if (!Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
18341bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
18358 if (!Callee ||
Callee->isVarArg())
18371bool PPCTargetLowering::
18372isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
18377 if (CI->getBitWidth() > 64)
18379 int64_t ConstVal = CI->getZExtValue();
18381 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
18390PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
18396 if ((Flags & FlagSet) == FlagSet)
18399 if ((Flags & FlagSet) == FlagSet)
18402 if ((Flags & FlagSet) == FlagSet)
18405 if ((Flags & FlagSet) == FlagSet)
18426 if ((FrameIndexAlign % 4) != 0)
18427 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18428 if ((FrameIndexAlign % 16) != 0)
18429 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18433 if ((FrameIndexAlign % 4) == 0)
18435 if ((FrameIndexAlign % 16) == 0)
18448 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18449 if ((Imm & 0x3) == 0)
18451 if ((Imm & 0xf) == 0)
18457 const APInt &ConstImm = CN->getAPIntValue();
18476 const APInt &ConstImm = CN->getAPIntValue();
18486 }
else if (RHS.getOpcode() ==
PPCISD::Lo && !RHS.getConstantOperandVal(1))
18506unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18511 if (!Subtarget.hasP9Vector())
18516 if (Subtarget.hasPrefixInstrs())
18519 if (Subtarget.hasSPE())
18528 unsigned ParentOp = Parent->
getOpcode();
18532 if ((ID == Intrinsic::ppc_vsx_lxvp) || (ID == Intrinsic::ppc_vsx_stxvp)) {
18533 SDValue IntrinOp = (ID == Intrinsic::ppc_vsx_lxvp)
18545 if (LSB->isIndexed())
18551 assert(MN &&
"Parent should be a MemSDNode!");
18556 "Not expecting scalar integers larger than 16 bytes!");
18559 else if (
Size == 32)
18566 else if (
Size == 256) {
18567 assert(Subtarget.pairedVectorMemops() &&
18568 "256-bit vectors are only available when paired vector memops is "
18576 else if (MemVT == MVT::f128 || MemVT.
isVector())
18607 FlagSet &= ~PPC::MOF_NoExt;
18612 bool IsNonP1034BitConst =
18616 IsNonP1034BitConst)
18629 int16_t ForceXFormImm = 0;
18644 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18660 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18666 if (PartVT == MVT::f64 &&
18667 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18669 Val = DAG.
getNode(ISD::BITCAST,
DL, MVT::f64, Val);
18676SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18680 EVT RetVT =
Op.getValueType();
18688 EVT ArgVT =
N.getValueType();
18693 Entry.IsZExt = !Entry.IsSExt;
18694 Args.push_back(Entry);
18702 (RetTy ==
F.getReturnType() ||
F.getReturnType()->
isVoidTy());
18715SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18716 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18718 if (
Op.getValueType() == MVT::f32)
18719 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18721 if (
Op.getValueType() == MVT::f64)
18722 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18727bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18729 return isLowringToMASSSafe(
Op) && Flags.hasNoSignedZeros() &&
18730 Flags.hasNoNaNs() && Flags.hasNoInfs();
18733bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18734 return Op.getNode()->getFlags().hasApproximateFuncs();
18737bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18741SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18742 const char *LibCallFloatName,
18743 const char *LibCallDoubleNameFinite,
18744 const char *LibCallFloatNameFinite,
18747 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18750 if (!isLowringToMASSFiniteSafe(
Op))
18751 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18754 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18755 LibCallDoubleNameFinite,
Op, DAG);
18759 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18760 "__xl_powf_finite",
Op, DAG);
18764 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18765 "__xl_sinf_finite",
Op, DAG);
18769 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18770 "__xl_cosf_finite",
Op, DAG);
18774 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18775 "__xl_logf_finite",
Op, DAG);
18779 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18780 "__xl_log10f_finite",
Op, DAG);
18784 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18785 "__xl_expf_finite",
Op, DAG);
18810 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18822 "Must be using PC-Relative calls when a valid PC-Relative node is "
18857 Base =
N.getOperand(0);
18865 EVT CNType = CN->getValueType(0);
18866 uint64_t CNImm = CN->getZExtValue();
18877 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
18879 int32_t
Addr = (int32_t)CNImm;
18884 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
18900 unsigned Opcode =
N.getOpcode();
18939 bool IsVarArg)
const {
18949 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
18985 return Intrinsic::ppc_atomicrmw_xchg_i128;
18987 return Intrinsic::ppc_atomicrmw_add_i128;
18989 return Intrinsic::ppc_atomicrmw_sub_i128;
18991 return Intrinsic::ppc_atomicrmw_and_i128;
18993 return Intrinsic::ppc_atomicrmw_or_i128;
18995 return Intrinsic::ppc_atomicrmw_xor_i128;
18997 return Intrinsic::ppc_atomicrmw_nand_i128;
19005 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
19007 assert(ValTy->getPrimitiveSizeInBits() == 128);
19011 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
19013 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
19014 Value *LoHi = Builder.CreateCall(RMW, {AlignedAddr, IncrLo, IncrHi});
19015 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
19016 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
19017 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
19018 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
19019 return Builder.CreateOr(
19020 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
19027 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
19029 assert(ValTy->getPrimitiveSizeInBits() == 128);
19033 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
19035 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
19036 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
19038 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
19041 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
19043 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
19044 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
19045 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
19046 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
19047 return Builder.CreateOr(
19048 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
static bool isConstantOrUndef(const SDValue Op)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
unsigned const TargetRegisterInfo * TRI
Promote Memory to Register
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool IsSelectCC(MachineInstr &MI)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool isPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool IsSelect(MachineInstr &MI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &S)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static const char AIXSSPCanaryWordName[]
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSMaxIdx, int RHSMinIdx, int RHSMaxIdx, int HalfVec, unsigned ValidLaneWidth, const PPCSubtarget &Subtarget)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget)
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
cl::opt< bool > ANDIGlueBug
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableP10StoreForward("disable-p10-store-forward", cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden, cl::init(false))
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
const SmallVectorImpl< MachineOperand > & Cond
const MachineOperand & RHS
static cl::opt< RegAllocEvictionAdvisorAnalysis::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development, "development", "for training")))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This file describes how to lower LLVM code to machine code.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static bool is64Bit(const char *name)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
An arbitrary precision integer that knows its signedness.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
This is an SDNode representing atomic operations.
This class holds the attributes for a function, its return value, and its parameters.
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
const Function & getFunction() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
@ INVALID_SIMPLE_VALUE_TYPE
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
An SDNode that represents everything that will be needed to construct a MachineInstr.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
PICLevel::Level getPICLevel() const
Returns the PIC level (small or large model)
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
uint64_t getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
bool useSoftFloat() const
const PPCFrameLowering * getFrameLowering() const override
bool needsSwapsForVSXMemOps() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
const PPCInstrInfo * getInstrInfo() const override
unsigned getCPUDirective() const
getCPUDirective - Returns the -m directive specified for the cpu.
POPCNTDKind hasPOPCNTD() const
bool isLittleEndian() const
bool isTargetLinux() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
bool isPredictableSelectIsExpensive() const
bool enableMachineScheduler() const override
Scheduling customization.
const PPCRegisterInfo * getRegisterInfo() const override
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName() - This method returns the name of a target specific DAG node.
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
void insertSSPDeclarations(Module &M) const override
Inserts necessary declarations for SSP (stack protection) purpose.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
uint64_t getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
bool useLoadStackGuardNode() const override
Override to support customized stack guard loading.
unsigned getStackProbeSize(const MachineFunction &MF) const
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
Value * getSDagStackGuard(const Module &M) const override
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
op_iterator op_end() const
op_iterator op_begin() const
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getRegister(Register Reg, EVT VT)
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
SDValue getCondCode(ISD::CondCode Cond)
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual Value * getSDagStackGuard(const Module &M) const
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
virtual AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
std::vector< ArgListEntry > ArgListTy
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
virtual bool useLoadStackGuardNode() const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static Type * getVoidTy(LLVMContext &C)
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
static IntegerType * getInt64Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Create or insert an LLVM Function declaration for an intrinsic, and return it.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_PPC_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ SEXT_LD_SPLAT
VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that sign-extends.
@ FCTIDUZ
Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for unsigned integers with round ...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ FSQRT
Square root instruction.
@ STRICT_FCFID
Constrained integer-to-floating-point conversion instructions.
@ DYNALLOC
The following two target-specific nodes are used for calls through function pointers in the 64-bit SV...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ TLSLD_AIX
[GP|G8]RC = TLSLD_AIX, TOC_ENTRY(module handle) Op that requires a single input of the module handle ...
@ CALL_RM
The variants that implicitly define rounding mode for calls with strictfp semantics.
@ STORE_VEC_BE
CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ MTVSRZ
Direct move from a GPR to a VSX register (zero)
@ SRL
These nodes represent PPC shifts.
@ VECINSERT
VECINSERT - The PPC vector insert instruction.
@ LXSIZX
GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an integer smaller than 64 bits into ...
@ FNMSUB
FNMSUB - Negated multiply-subtract instruction.
@ RFEBB
CHAIN = RFEBB CHAIN, State - Return from event-based branch.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ GET_TLS_ADDR
x3 = GET_TLS_ADDR x3, Symbol - For the general-dynamic TLS model, produces a call to __tls_get_addr(s...
@ XXSPLTI32DX
XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ FRE
Reciprocal estimate instructions (unary FP ops).
@ ADDIS_GOT_TPREL_HA
G8RC = ADDIS_GOT_TPREL_HA x2, Symbol - Used by the initial-exec TLS model, produces an ADDIS8 instruc...
@ CLRBHRB
CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
@ STORE_COND
CHAIN,Glue = STORE_COND CHAIN, GPR, Ptr The store conditional instruction ST[BHWD]ARX that produces a...
@ SINT_VEC_TO_FP
Extract a subvector from signed integer vector and convert to FP.
@ EXTRACT_SPE
Extract SPE register component, second argument is high or low.
@ XXSWAPD
VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little endian.
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ ATOMIC_CMP_SWAP_8
ATOMIC_CMP_SWAP - the exact same as the target-independent nodes except they ensure that the compare ...
@ ST_VSR_SCAL_INT
Store scalar integers from VSR.
@ VCMP
RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* instructions.
@ BCTRL
CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a BCTRL instruction.
@ BUILD_SPE64
BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and EXTRACT_ELEMENT but take f64 arguments in...
@ LFIWZX
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...
@ RET_GLUE
Return with a glue operand, matched by 'blr'.
@ SCALAR_TO_VECTOR_PERMUTED
PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to place the value into the least sign...
@ EXTRACT_VSX_REG
EXTRACT_VSX_REG = Extract one of the underlying vsx registers of an accumulator or pair register.
@ STXSIX
STXSIX - The STXSI[bh]X instruction.
@ MAT_PCREL_ADDR
MAT_PCREL_ADDR = Materialize a PC Relative address.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ XXSPLT
XXSPLT - The PPC VSX splat instructions.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ XXPERMDI
XXPERMDI - The PPC XXPERMDI instruction.
@ ADDIS_DTPREL_HA
G8RC = ADDIS_DTPREL_HA x3, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction t...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Can be used by the initial-exec and local-exec TLS models,...
@ MTVSRA
Direct move from a GPR to a VSX register (algebraic)
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_GOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ ADDI_DTPREL_L
G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction ...
@ BCTRL_LOAD_TOC
CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl instruction and the TOC reload r...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ FCFID
FCFID - The FCFID instruction, taking an f64 operand and producing and f64 value containing the FP re...
@ CR6SET
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
@ LBRX
GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a byte-swapping load instruction.
@ GET_TLS_MOD_AIX
x3 = GET_TLS_MOD_AIX _$TLSML - For the AIX local-dynamic TLS model, produces a call to ....
@ LD_VSX_LH
VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a v2f32 value into the lower ha...
@ PROBED_ALLOCA
To avoid stack clash, allocation is performed by block and each block is probed.
@ XXMFACC
XXMFACC = This corresponds to the xxmfacc instruction.
@ ADDIS_TLSGD_HA
G8RC = ADDIS_TLSGD_HA x2, Symbol - For the general-dynamic TLS model, produces an ADDIS8 instruction ...
@ ACC_BUILD
ACC_BUILD = Build an accumulator register from 4 VSX registers.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ LXVD2X
VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
@ XSMAXC
XSMAXC[DQ]P, XSMINC[DQ]P - C-type min/max instructions.
@ CALL
CALL - A direct function call.
@ MTCTR
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
@ TC_RETURN
TC_RETURN - A tail call return.
@ STFIWX
STFIWX - The STFIWX instruction.
@ LD_SPLAT
VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory instructions such as LXVDSX,...
@ VCMP_rec
RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the altivec VCMP*_rec instructions.
@ MFFS
F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
@ PADDI_DTPREL
G8RC = PADDI_DTPREL x3, Symbol - For the pc-rel based local-dynamic TLS model, produces a PADDI8 inst...
@ BUILD_FP128
Direct move of 2 consecutive GPR to a VSX register.
@ VEXTS
VEXTS, ByteWidth - takes an input in VSFRC and produces an output in VSFRC that is sign-extended from...
@ TLS_LOCAL_EXEC_MAT_ADDR
TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address when using local exec access ...
@ VPERM
VPERM - The PPC VPERM Instruction.
@ ADDIS_TLSLD_HA
G8RC = ADDIS_TLSLD_HA x2, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction th...
@ XXSPLTI_SP_TO_DP
XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for converting immediate single prec...
@ GET_TLSLD_ADDR
x3 = GET_TLSLD_ADDR x3, Symbol - For the local-dynamic TLS model, produces a call to __tls_get_addr(s...
@ ADDI_TLSGD_L
x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS model, produces an ADDI8 instruction t...
@ DYNAREAOFFSET
This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to compute an offset from native ...
@ PAIR_BUILD
PAIR_BUILD = Build a vector pair register from 2 VSX registers.
@ STRICT_FADDRTZ
Constrained floating point add in round-to-zero mode.
@ FTSQRT
Test instruction for software square root.
@ FP_EXTEND_HALF
FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or lower (IDX=1) half of v4f32 to v2f6...
@ CMPB
The CMPB instruction (takes two operands of i32 or i64).
@ VECSHL
VECSHL - The PPC vector shift left instruction.
@ ADDI_TLSLD_L
x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction tha...
@ FADDRTZ
F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding towards zero.
@ ZEXT_LD_SPLAT
VSRC, CHAIN = ZEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that zero-extends.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
@ EXTSWSLI
EXTSWSLI = The PPC extswsli instruction, which does an extend-sign word and shift left immediate.
@ STXVD2X
CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
@ TLSGD_AIX
GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY Op that combines two re...
@ UINT_VEC_TO_FP
Extract a subvector from unsigned integer vector and convert to FP.
@ GET_TPOINTER
x3 = GET_TPOINTER - Used for the local- and initial-exec TLS model on 32-bit AIX, produces a call to ...
@ LXVRZX
LXVRZX - Load VSX Vector Rightmost and Zero Extend This node represents v1i128 BUILD_VECTOR of a zero...
@ MFBHRBE
GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch history rolling buffer entry.
@ FCFIDU
Newer FCFID[US] integer-to-floating-point conversion instructions for unsigned integers and single-pr...
@ FSEL
FSEL - Traditional three-operand fsel node.
@ SWAP_NO_CHAIN
An SDNode for swaps that are not associated with any loads/stores and thereby have no chain.
@ LOAD_VEC_BE
VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
@ LFIWAX
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
@ STBRX
CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a byte-swapping store instruction.
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ TLS_DYNAMIC_MAT_PCREL_ADDR
TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for TLS global address when using dyna...
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
@ Define
Register definition.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
bool isa_and_nonnull(const Y &Val)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Mod
The access may modify the value stored in memory.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
static constexpr roundingMode rmTowardZero
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)